查找两个具有相同字段的表之间不共享的SQL行

3

我有两个具有相同字段并且共享许多行的表格。我想要列出其中一个表格中无法匹配到另一个表格中的所有行。具体来说,这两个表格是实验的两个不同版本,结果略有不同。例如:

|TableA|
--------
horse
cat
cow
table

|TableB|
--------
horse
cat
chair

我希望能看到TableA缺少chair,并且在另一个查询中,TableB缺少cowtableTableA中删除。我的想法是对所有字段进行外部连接,然后筛选出其中包含空值的行,但这种方法似乎过于笨重。是否有更优雅/高效的方法?
3个回答

12

使用 NOT IN:

SELECT a.column
  FROM TABLE_A a
 WHERE a.column NOT IN (SELECT b.column
                          FROM TABLE_B b)

使用 NOT EXISTS:

如果您需要比较多个列,这种方法是很好的选择...

SELECT a.column
  FROM TABLE_A a
 WHERE NOT EXISTS(SELECT NULL
                    FROM TABLE_B b
                   WHERE b.column = a.column)

使用LEFT JOIN/IS NULL:

   SELECT a.column
     FROM TABLE_A a
LEFT JOIN TABLE_B b ON b.column = a.column
    WHERE b.column IS NULL

由于表别名的存在,您可以交换表名而不更改查询的其余部分,以查看相反的结果--即不在TABLE_A中的TABLE_B行。


谢谢,最终我使用了你的左连接版本。 - Rich

0

在使用IN子句处理可空列时要小心


不是真正的答案,而更像是一条评论。您能否对答案或我的原始问题发表评论,并解释为什么在可空列上使用IN可能是不好的? - Rich

0
如果您想获取左表中存在而右表中不存在的所有行,以及右表中存在而左表中不存在的所有行的单个列表:
CREATE TABLE test1 (
idOne int identity primary key
,nameOne nvarchar (3) 
)
CREATE TABLE test2 (
idTwo int identity primary key
,nameTwo nvarchar (3) 
)
INSERT INTO test1 (nameOne) VALUES
('one'),
('two'),
('thr')
INSERT INTO test2 (nameTwo) VALUES
('one'),
('tre')

SELECT 'test2 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
RIGHT JOIN test2 t2 ON
t1.idOne = t2.idTwo and 
t1.nameOne = t2.nameTwo
WHERE idONE is NULL
OR idTwo is NULL
UNION ALL 
SELECT 'test1 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
LEFT JOIN test2 t2 ON
t1.idOne = t2.idTwo and 
t1.nameOne = t2.nameTwo
WHERE idOne is NULL
OR idTwo is NULL

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