如何排除不与另一个表联接的行?

我有两个表,一个是主键,另一个是外键。

我想从主表中提取数据,只有当辅助表 没有有一个包含它的键的条目时才这样做。与简单的内部连接相反,内部连接只返回通过该键连接在一起的行。

152493 次浏览
SELECT
*
FROM
primarytable P
WHERE
NOT EXISTS (SELECT * FROM secondarytable S
WHERE
P.PKCol = S.FKCol)

一般来说,(NOT) EXISTS是比 (NOT) IN(LEFT) JOIN更好的选择

使用“不存在”左连接:

SELECT p.*
FROM primary_table p LEFT JOIN second s ON p.ID = s.ID
WHERE s.ID IS NULL
SELECT P.*
FROM primary_table P
LEFT JOIN secondary_table S on P.id = S.p_id
WHERE S.p_id IS NULL

如果您想要从 First Table 中选择也出现在 Second Table 中的列,那么在这种情况下也可以使用 EXCEPT。在这种情况下,列名也可以不同,但数据类型应该相同。

例如:

select ID, FName
from FirstTable
EXCEPT
select ID, SName
from SecondTable

alt text

SELECT <select_list>
FROM Table_A A
LEFT JOIN Table_B B
ON A.Key = B.Key
WHERE B.Key IS NULL

Full image of join alt text

From aticle : http://www.codeproject.com/KB/database/Visual_SQL_Joins.aspx

这对于在 COGNOS 中使用非常有帮助,因为允许在 COGNOS 中创建 SQL“ Not in”语句,但运行时间太长。我在 Cognos 中将表 A 手动编码为 A 键“ not in”B 键,以连接到表 B,但查询时间太长/5分钟后没有返回结果。

对于其他在 Cognos 中寻找“ NOT IN”解决方案的人,以下是我所做的。在 Cognos 中创建一个查询,通过选择链接类型将表 A 和表 B 与 LEFT JOIN 连接在一起: 表 A 键在表 B 中有“0到 N”值,然后为表 B 添加一个 Filter (这些值对应于 Where 子句)。

跑得又快又好。

另一个解决办法是:

SELECT * FROM TABLE1 WHERE id NOT IN (SELECT id FROM TABLE2)