【发布时间】:2018-11-06 23:06:32
【问题描述】:
【问题讨论】:
-
样本数据和期望的结果真的很有帮助。
-
不一定是左连接。
【问题讨论】:
一种方法是minus:
select . . .
from a
minus
select . . .
from b
minus
select . . .
from c;
或者,not exists:
select a.*
from a
where not exists (select 1 from b where . . . ) and
not exists (select 1 from c where . . . );
你没有说明匹配条件是什么,所以我用. . .作为一般性。
这两个版本不一样。第一个返回来自a 的列的唯一组合,其中相同的列不在b 或c 中。第二个返回来自a 的所有 列,其中另一组不在b 或c 中。
【讨论】:
EXCEPT ALL 或 MINUS ALL 就好了,比如 DB2 和 PostgreSQL
如果您必须使用LEFT JOIN 来实现真正的anti join,那么请执行以下操作:
SELECT *
FROM a
LEFT JOIN b ON b.a_id = a.a_id
LEFT JOIN c ON c.a_id = a.a_id
WHERE b.a_id IS NULL
AND c.a_id IS NULL
内容如下:
FROM: 从 a 中获取所有行LEFT JOIN:也可以选择从 b 和 c 中获取匹配的行WHERE:其实没有。只保留 a 中那些在 b 和 c 中没有匹配的行不过,使用NOT EXISTS() 是一种更优雅的反连接方式。我倾向于不推荐 NOT IN(),因为这三个值逻辑的微妙含义 - 这可能导致无法获得任何结果。
很多人喜欢使用维恩图来说明连接。我认为这是一个坏习惯,维恩图模型集合操作(比如UNION、INTERSECT,或者在你的情况下是EXCEPT/MINUS)非常好。 Joins are filtered cross products, which is an entirely different kind of operation. I've blogged about it here.
【讨论】:
选择不在 B 或 C 或 A 中的内容 内连接 B 内连接 C
Select * from A
where A.id not in ( select coalesce(b.id,c.id) AS ID
from b full outer join c on (b.id=c.id) )
或者也:---你不需要加入,所以你可以避免这样做
select * from A
where a.id not in (select coalesce (B.ID,C.ID) AS ID from B,C)
【讨论】:
我会这样做:
SELECT t1.name
FROM table1 t1
LEFT JOIN table2 t2 ON t2.name = t1.name
WHERE t2.name IS NULL
有人已经问过与您的问题相关的问题,您应该看到它 here
【讨论】: