完全外部联接会重复使用Union吗?

时间:2018-11-02 02:29:00

标签: mysql

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

Reference Link

  
      
  • 完全(外部)联接:如果存在匹配项,则返回所有记录   左桌或右桌
  •   

尽管显然不支持此功能。我环顾四周,并遇到了这个公认的答案: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个表中?

例如

  
      
  • 左(外)联接:返​​回左表中的所有记录,然后返回   右表中匹配的记录

  •   
  • 右(外)联接:全部返回   右表中的记录,和左表中的匹配记录   表格

  •   

联盟左外表+(左匹配=右匹配)x2 +右外表

enter image description here

我确信答案是可行的,因为社区对此表示信任。但是我仍然对它的工作方式感到困惑,希望有人能帮助我更好地理解。

1 个答案:

答案 0 :(得分:0)

要重申您所引用的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

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

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

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

  • 在联合查询中,将过滤掉出现在第一个表中的重复记录。这很微妙,因为这里的两个来源可能产生重复。首先,第一个表本身可能有重复项。其次,联接可能会产生重复。 所有重复项将从UNION ALL中删除。
  • 但是,在并集所有查询中,不会删除 no 重复项。可能恰好出现在第一个表中的重复记录将保留在最终结果集中,而联接产生的所有重复记录也将保留在最终结果集中。

这是一个冗长的答案,但希望它能使您相信,如果重复,则接受的答案的UNIONUNION版本可能不会生成相同的结果集。