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


86

我有两个表,一个有主键,另一个有它作为外键。

我只想从辅助表提取数据,除非辅助表没有包含其键的条目。与简单内部联接相反,后者仅返回通过该键联接在一起的行。

Answers:


269

替代文字

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

完整图片 替代文字

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


9
最后!他们为什么在课本中没有这些?为什么我在uni的讲师没有这些?他们使用了世界上最糟糕的解释,而不是接近这些解释!
pythonian29033

4
这是黄金。我讨厌写评论,但没有内容,但赞不绝口,但是加油!这是一个了不起的答案。谢谢@Pranay Rana。
0xbe5077ed 2016年

1
请为我解释,为什么B.Key IS NULL但我们仍然具有可比性A.Key = B.Key
做Nhu Vy

1
@DoNhuVy很简单,比较是在“ ON”子句中,如果没有匹配的行,则在LEFT或RIGHT连接中,然后将连接所有NULL的行,然后测试IS NULL以知道没有匹配的行。(顺便说一句,这仅适用于如果要测试的字段不是NULL,即由于某些其他原因而不能为NULL)
Gregory Magarshak

我正在使用以下查询:从#PurgeFilesListNew A中完全选择A. *来自#DoNotPurgeFilesListNew A的完整外部连接A.AccountID为NULL或B.AccountID为NULL基本上,我在“ ON”子句中比较两个值。它工作正常,但查询返回的空行用于那些不匹配的行。如何解决呢?请帮助
HarshSharma

10
SELECT
   *
FROM
   primarytable P
WHERE
   NOT EXISTS (SELECT * FROM secondarytable S
     WHERE
         P.PKCol = S.FKCol)

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


好吧,他没有发布使用DBRMS的内容,但是在MySql中LEFT JOIN表现出色NOT EXIST
Scrum Meister 2010年

@Scrum Meister:我说得更快吗?搜索IN vs EXISTS vs JOIN以发现语义和逻辑差异...
gbn 2010年

@gbn对不起,我认为“更好的选择”意味着您更快。然后,您能解释一下哪种方法更好吗? explainextended.com/2009/09/18/...
Scrum的梅斯特

1
@The Scrum Meister:通常,任何一种JOIN都可能需要DISTINCT。列表中为null的NOT IN给出false。IN / EXISTS的行为相同。但是,除非您喜欢不一致,否则唯一的“安全”构造是(NOT)EXISTS
gbn 2010年


4

使用“不存在”左联接:

SELECT p.*
FROM primary_table p LEFT JOIN second s ON p.ID = s.ID
WHERE s.ID IS NULL


3
SELECT P.*
FROM primary_table P
LEFT JOIN secondary_table S on P.id = S.p_id
WHERE S.p_id IS NULL

2
有一个问题..如果我们使用条件P.key = S.key然后说where S.key IS NULL,那那P.key是否也为null?
松吉

2

如果要从“第二张表”中也存在的“第一张表”中选择列,则在这种情况下,也可以使用EXCEPT。在这种情况下,列名也可以不同,但​​数据类型应该相同。

例:

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

0

这对在COGNOS中使用很有帮助,因为允许在Cognos中创建SQL“ Not in”语句,但运行时间太长。我已经手动将表A编码为Co.s中的表B,而不是B.key中的A.key联接到表B,但是查询花费的时间太长/ 5分钟后未返回结果。

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

快速奔跑,像个魅力。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.