当第二个表中没有匹配项时,我想从一个表中检索所有记录。
所以它有点与内部连接相反。
您需要一个 LEFT JOIN WHERE IS NULL 查询(又名外连接):
SELECT table1.*
FROM table1
LEFT OUTER JOIN table2
ON table1.id = table2.id
WHERE table2.id IS NULL
或不在:
SELECT *
FROM table1
WHERE id NOT IN (SELECT id FROM table2)
这是一个外部连接:
SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b USING(x)
假设你有:
表A:
a | x
-----
1 | 1
3 | 3
表 B:
b | x
-------
1 | 'a'
2 | 'b'
那么上面的查询会给你
a | b | x
------------
1 | 'a' | 1
3 | NULL | 3
如果你想
a | b | x
----------------
1 | 'a' | 1
NULL | 'b' | 2
3 | NULL | 3
你必须使用FULL OUTER JOIN
而不是LEFT JOIN
.
编辑:正如 Larry Lustig 告诉我的(我认为在重读问题后是正确的),OP 不需要 B 中的任何行。所以查询应该是:
SELECT a.*
FROM tableA AS a
LEFT JOIN tableB AS b USING(x)
WHERE b.x IS NULL
这将产生
a | x
-------
3 | 3
你有三个选择:
相关子查询。
SELECT * FROM TableA WHERE NOT EXISTS (SELECT * FROM TableB WHERE TableB.ID = TableA.ID)
不相关的子查询。
SELECT * FROM TableA WHERE ID NOT IN(从 TableB 中选择 ID)
带有 NULL 消除的 OUTER JOIN。
SELECT * FROM TableA LEFT [OUTER] JOIN TableB ON TableA.ID = TableB.ID WHERE TableB.ItsPrimaryKey 不为空
在最后一个例子中,一些 DBMS 需要 OUTER 这个词,有些允许,有些根本不允许。
根据 DBMS,各种选项可能会产生不同的执行计划和不同的性能。选择性能良好且最能表达您意图的那个。
内连接的“对立面”称为外连接。
我相信您正在寻找 FULL OUTER JOIN(适用于 Oracle 9i+)。
编辑:没有很好地阅读您的问题...如果您只想要第二个表的 NULL 值,请使用 LEFT JOIN
外连接。从技术上讲,可能是完全外连接;)
在 Johannes Weiß 的解决方案中添加关于在表 a 中查找对象而在表 b 中没有对象的其他问题的解决方案:
SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b
USING(x)
WHERE b.foo IS NULL
您正在寻找 LEFT JOIN 或 FULL OUTER JOIN 虽然并非所有 DBMS 都支持 FULL。
使用 UNION 可以模拟它,例如 MySQL:
SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id