【发布时间】:2020-02-28 21:55:51
【问题描述】:
我需要比较两个表中的记录:X 和 Y。每条记录都有两个 id:ID1 和 ID2。 ID1 或 ID2 在任一表中都可以为空,但不能同时为空。我需要生成一个包含两个表中所有信息的视图:
- X.ID1 = Y.ID1 和 X.ID2 = Y.ID2 的行
- X.ID1 = Y.ID1 但 X.ID2 Y.ID2 的行
- X.ID1 Y.ID1 但 X.ID2 = Y.ID2 的行
- X.ID1 和 Y.ID1 根本没有任何匹配项的行
- X.ID2 和 Y.ID2 根本没有任何匹配项的行
例子:
X: Y:
|---------------| |---------------|
| ID1 | ID2 | | ID1 | ID2 |
|---------------| |---------------|
| 1 | A | | 1 | A |
| 2 | B | | 2 | C |
| 3 | NULL | | NULL | B |
| NULL | D | | 5 | NULL |
|---------------| |---------------|
Output:
|---------------------------------------|
| XID1 | YID1 | XID2 | YID2 | SRC |
|---------------------------------------|
| 1 | 1 | A | A | X+Y |
| 2 | 2 | B | C | X+Y |
| 3 | NULL | NULL | NULL | X |
| NULL | 5 | NULL | NULL | Y |
| 2 | NULL | B | B | X+Y |
| NULL | 2 | NULL | C | Y |
| NULL | NULL | D | NULL | X |
|---------------------------------------|
我的第一个明显的解决方案是做一个FULL OUTER JOIN:
SELECT … FROM X FULL OUTER JOIN Y ON X.ID1 = Y.ID1 OR X.ID2 = Y.ID2
这可行,但连接中的条件性能很差,并且此视图最多需要一分钟才能运行。删除条件将执行时间缩短到不到一秒,但随后我失去了其中一个 ID 的匹配。
如何在不使用条件连接的情况下优雅地实现上述目标?我试过了:
- 通过连接两个 ID 进行连接,但这仅在两个 ID 匹配时才匹配
- 执行
CROSS JOIN并按X.ID1=Y.ID1 OR X.ID2=Y.ID2过滤,但这会丢失没有任何匹配项的情况。这是最有前途的方法。 - 对 X 和 Y 执行
UNION ALL,然后按 ID1 和 ID2 分组,但这再次仅在两个 ID 匹配时才匹配
【问题讨论】:
-
(1) MySQL 不支持
full join,所以我去掉了标签。 (2) 提供样本数据和期望的结果。
标签: sql sql-server