【问题标题】:LEFT JOIN THREE tables左连接三个表
【发布时间】:2018-11-06 23:06:32
【问题描述】:

如何创建sql查询来选择不同的表A数据 如图

谢谢

【问题讨论】:

  • 样本数据和期望的结果真的很有帮助。
  • 不一定是左连接。

标签: sql oracle


【解决方案1】:

一种方法是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 的列的唯一组合,其中相同的列不在bc 中。第二个返回来自a所有 列,其中另一组不在bc 中。

【讨论】:

  • 啊,是的。要是 Oracle 有 EXCEPT ALLMINUS ALL 就好了,比如 DB2 和 PostgreSQL
【解决方案2】:

如果您必须使用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(),因为这三个值逻辑的微妙含义 - 这可能导致无法获得任何结果

关于使用维恩图进行连接的附注

很多人喜欢使用维恩图来说明连接。我认为这是一个坏习惯,维恩图模型集合操作(比如UNIONINTERSECT,或者在你的情况下是EXCEPT/MINUS)非常好。 Joins are filtered cross products, which is an entirely different kind of operation. I've blogged about it here.

【讨论】:

    【解决方案3】:

    选择不在 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)
    

    【讨论】:

    • 不,在连接中,至少存在 b.id 或 c.id,所以我确定至少有一个值 exixts(我假设 ID 字段不为空)
    【解决方案4】:

    我会这样做:

    SELECT t1.name
    FROM table1 t1
    LEFT JOIN table2 t2 ON t2.name = t1.name
    WHERE t2.name IS NULL
    

    有人已经问过与您的问题相关的问题,您应该看到它 here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-01
      • 1970-01-01
      • 2016-07-02
      • 2014-10-26
      • 1970-01-01
      • 2014-08-05
      相关资源
      最近更新 更多