2014-01-28 39 views
1

我需要比較select查詢中的2個參數和子查詢中的2個參數。 實施例:將子查詢結果與2個參數對比較

SELECT * 
FROM pupil 
WHERE name NOT IN (SELECT name FROM bad_names) 

這個例子僅包含一個參數進行比較。但是如果我需要比較子查詢結果和一對2參數呢? 這將工作:

SELECT * 
FROM pupil 
WHERE name||lastname NOT IN (
    SELECT name||lastname FROM bad_name_lastname_combinations) 

所以字符串連接是做到這一點的唯一途徑?

回答

2

PostgreSQL是足夠的靈活性,以row constructor and NOT IN做到這一點:

row_constructor NOT IN (subquery) 

此形式的NOT IN的左側是行構造函數,如4.2.13節中所述。右側是一個帶圓括號的子查詢,它必須返回與左側表達式一樣多的列。對左側表達式進行評估並逐行比較子查詢結果的每一行。如果僅找到不相等的子查詢行(包括子查詢不返回任何行),則NOT IN的結果爲「true」。如果找到任何相等的行,結果是「假」。

所以,你可以做到這一點的直線前進的方式,如果你寫的row_constructor正確:

select * 
from pupil 
where (name, lastname) not in (
    select name, lastname 
    from bad_last_name_combinations 
) 

演示:http://sqlfiddle.com/#!15/a6863/1

+0

非常感謝。 – user1561346

2
select * 
from pupil p 
where not exists 
     (
     select * 
     from bad_names bn 
     where bn.name = p.name 
       and bn.lastname = p.lastname 
     ) 
+0

請解釋一下你是如何得到你的解決方案,而不是僅僅給回答OP,以便答案更一般。 – ArtB

+0

這項工作也像一個魅力。謝謝。 – user1561346

0

您可以使用NOT EXISTS命令

SELECT * 
FROM pupil p 
WHERE NOT EXISTS 
(
    SELECT 1 
    FROM bad_name_lastname_combinations b 
    WHERE b.name = p.name OR b.lastname = p.lastname) 
) 
+0

謝謝。如果您將OR更改爲AND,它將按照原樣工作。 – user1561346

1

您可以用left outer join做到這一點:

SELECT p.* 
FROM pupil p left outer join 
    bad_name_lastname_combinations bnlc 
    on p.name = bnlc.name and p.lastname = bnlc.lastname 
WHERE bnlc.name is null; 
+0

謝謝。也適用。 – user1561346

+0

@ user1561346。 。 。我更喜歡'left outer join'方法,因爲它是標準的SQL並且受到任何數據庫的支持。 –