我正在尝试使用SQL完成完全外部联接。
- 完全(外部)联接:如果存在匹配项,则返回所有记录 左桌或右桌
尽管显然不支持此功能。我环顾四周,并遇到了这个公认的答案: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 +右外表
我确信答案是可行的,因为社区对此表示信任。但是我仍然对它的工作方式感到困惑,希望有人能帮助我更好地理解。
答案 0 :(得分:0)
要重申您所引用的accepted answer,我将同时引用UNION
和UNION 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}}。t1
的所有公用记录和唯一记录。但是t2
会过滤掉那些重复的通用记录,而不会更改结果集,因为我们假设没有重复记录。UNION
选择性地删除重复的公用记录。这样可以确保WHERE t1.id IS NULL
的后半部分仅添加第二个表唯一的记录。现在,如果第一个表本身恰好具有重复项,则将发生以下情况:
UNION ALL
中删除。这是一个冗长的答案,但希望它能使您相信,如果重复,则接受的答案的UNION
和UNION
版本可能不会生成相同的结果集。