您需要的关系运算符是 semi Difference aka antijoin。
大多数 SQL 产品缺少显式的半差分运算符或关键字。标准 SQL-92 没有(它有一个MATCH (subquery)
semijoin 谓词,但是,虽然很容易不这么想,但语义NOT MATCH (subquery)
与半差分不同;FWIW 真正的关系语言教程 D成功地使用了NOT MATCHING
半差分)。
半差分当然可以使用其他 SQL 谓词来编写。最常见的是:在WHERE
子句中测试空值的外连接,紧随其后的是EXISTS
or IN (subquery)
。如果您的 SQL 产品支持并且再次取决于数据(特别是当两个表的标题相同时),使用EXCEPT
(相当于在 Oracle 中)是另一种可能的方法。MINUS
就个人而言,我更喜欢EXISTS
在 SQL 中使用半差分连接,因为连接子句在书面代码中更接近,并且不会导致连接表上的投影,例如
SELECT *
FROM TABLE1 W
WHERE NOT EXISTS (
SELECT *
FROM TABLE2 V
WHERE W.NAME = V.NAME
);
与(与外连接方法相同)一样,如果子查询中的子句涉及空值,NOT IN (subquery)
则需要格外小心(提示:如果子查询中的子句由于存在空值而评估为 UNKNOWN,那么它将被强制为 FALSE ,这可能会产生意想不到的结果)。WHERE
WHERE
EXISTS
更新(3 年后):我已经转向更喜欢NOT IN (subquery)
,因为它更具可读性,如果您担心空值的意外结果(您应该)那么完全停止使用它们,我在很多年前就这样做了。
一种更具可读性的方法是不需要范围变量W
,V
例如
SELECT * FROM TABLE1 WHERE name NOT IN ( SELECT name FROM TABLE2 );