检查表A中的条目是否存在于表B中。

108

我有一个定义表,我知道它没有被很好地维护,我们称之为表A。我有另一个表(称之为表B),它要小得多,理想情况下应该是表A的子集,但我知道表A有些过时,不包含表B中的新条目。

请注意,表A和表B具有不同的列。

Table A:
ID, Name, blah, blah, blah, blah

Table B:
ID, Name

我想要在B表中选择所有的行,其中B表的ID在A表中不存在。这不仅仅是匹配A表中的行;我只想要B表中ID完全不存在于A表中的行。

5个回答

211
SELECT *
FROM   B
WHERE  NOT EXISTS (SELECT 1 
                   FROM   A 
                   WHERE  A.ID = B.ID)

21
从表B中选择所有行,其中ID不在从表A中选择ID的结果集中。 - vakio
2
@vakio 感谢您的提问。您应该将您的评论作为答案发布。 - Analytical Monk
@AnalyticalMonk 我希望你意识到这是完全相同的查询,将产生完全相同的结果。只是语法上有一点点不同,仅此而已。 - gdoron
@gdoron 我确实意识到了。然而,尽管差异很小,我更喜欢这种语法。如果我的建议违反了 SO 政策,我深感抱歉。 - Analytical Monk
2
@ManosKounelakis Select 1 表示每行返回 1 作为结果。通常用于表示结果无关紧要,只有存在性才是重要的。您可以将 1 更改为任何有效值(*、1、2、3、column1、column2),而结果不会改变。 - gdoron
显示剩余2条评论

39

几乎适用于所有环境的经典答案是

SELECT ID, Name, blah, blah
FROM TableB TB
LEFT JOIN TableA TA
ON TB.ID=TA.ID
WHERE TA.ID IS NULL

有时候 NOT EXISTS 可能没有被实现(不起作用)。


3
这个查询比SELECT * FROM B WHERE NOT EXISTS (SELECT 1 FROM A WHERE A.ID = B.ID) 更高效。 - teteArg
DUAL是一种特殊的一行一列表,在所有Oracle数据库中默认存在。DUAL的所有者是SYS(SYS拥有数据字典,因此DUAL是数据字典的一部分),但每个用户都可以访问DUAL。该表具有一个名为DUMMY的单个VARCHAR2(1)列,其值为“X”。MySQL允许在不需要任何表数据的查询中指定DUAL作为表。在SQL Server中,DUAL表不存在,但您可以创建一个。 - David Kariuki
2
比 NOT EXISTS 更快 - lisandro

15

如果您决定使用 EXISTS,可以在SQL Server中使用以下代码:

SELECT * FROM TableB as b
WHERE NOT EXISTS
(
   SELECT * FROM TableA as a
   WHERE b.id = a.id
)

11

这也是起作用的

SELECT *
FROM tableB
WHERE ID NOT IN (
  SELECT ID FROM tableA
);

我喜欢这个!非常直接简单易懂。 - cavalcantelucas
这是对我的情况来说最简单和高效的答案。我只是想要一次性检查另一个表中所有行的id是否存在。 - wcsSunil

0

或者如果“NOT EXISTS”未被实现

SELECT *
FROM   B
WHERE (SELECT count(*)  FROM   A WHERE  A.ID = B.ID) < 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接