【问题标题】:Full Outer Join get repeated with Union?完全外连接与联合重复?
【发布时间】:2018-11-02 02:28:59
【问题描述】:

我正在尝试使用我的 SQL 完成完全外部联接。

Reference Link

  • FULL (OUTER) JOIN:当有匹配时返回所有记录 左表或右表

虽然这显然不受支持。我环顾四周,发现了这个公认的答案:https://stackoverflow.com/a/4796911/3859456

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

虽然这不会在我们进行联合时至少重复两次匹配的记录吗?如果没有,联合是否会自动将匹配的记录覆盖到 2 个表中?

例如

  • LEFT (OUTER) JOIN:返回左表的所有记录,然后 右表中的匹配记录

  • 右(外)连接:返回所有 右表中的记录,和左表中的匹配记录 表格

Union Left-Outer-Table + (left-matched = right-matched)x2 + Right-Outer-Table

我确信答案在社区信任的情况下有效。但我仍然对它的工作原理感到困惑,希望有人能帮助我更好地理解。

【问题讨论】:

    标签: mysql


    【解决方案1】:

    为了重申您所指的accepted answer,我将引用UNIONUNION ALL 两个版本:

    SELECT * FROM t1
    LEFT JOIN t2 ON t1.id = t2.id
    UNION
    SELECT * FROM t1
    RIGHT JOIN t2 ON t1.id = t2.id
    

    SELECT * FROM t1
    LEFT JOIN t2 ON t1.id = t2.id
    UNION ALL
    SELECT * FROM t1
    RIGHT JOIN t2 ON t1.id = t2.id
    WHERE t1.id IS NULL
    

    如果连接生成no 个重复项,则这两个查询将返回相同的结果集。原因可以解释为:

    • UNION/UNION ALL 的前半部分返回两个表之间共有的所有记录(根据我们的假设,没有重复),它还返回第一个表 t1 唯一的记录。李>
    • union 查询的后半部分返回第二个表t2 的所有公共记录和唯一记录。但是UNION 过滤掉了那些重复的公共记录而不改变结果集,因为我们假设没有重复。
    • union all 查询的后半部分使用WHERE t1.id IS NULL 选择性地删除重复的公共记录。这确保了UNION ALL 的后半部分仅添加第二个表唯一的记录。

    现在,如果第一个表本身恰好有重复项,则会发生以下情况:

    • 在联合查询中,第一个表中出现的重复记录将被过滤掉。这很微妙,因为这里的两个来源可能会产生重复。首先,第一个表本身可能存在重复项。其次,连接可能会产生重复。 所有重复项将从UNION 中删除。
    • 但是,在 union all 查询中,no 个重复项将被删除。可能碰巧出现在第一个表中的重复记录将在最终结果集中完好无损地保留下来,连接产生的任何重复记录也是如此。

    这是一个冗长的答案,但希望它能说服您在重复的情况下,接受答案的UNIONUNION ALL 版本可能不会生成相同的结果集。

    【讨论】:

    • 感谢您澄清这一点。从中学到了很多关于Union的知识!
    猜你喜欢
    • 2017-06-09
    • 2016-12-19
    • 1970-01-01
    • 2015-03-31
    • 2017-06-10
    • 2018-07-12
    • 2011-12-26
    • 2014-09-23
    • 1970-01-01
    相关资源
    最近更新 更多