sql - 如果一个或多个表中缺少该键,您能否在同一个键上连接三个表?
问题描述
我正在使用三个表并使用相同的主键将它们全部连接在一起,但不能保证所有值都存在于所有三个表中,并且我希望每个值最终都出现在最终连接中。
例如,有一个TableA
、TableB
和TableC
,每个只有一列(我们只称列colA
、colB
和colC
)。值10
存在于TableA
and中TableC
,但不存在TableB
。
SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.colA = TableB.colB
FULL OUTER JOIN TableC ON TableB.colB = TableC.colC;
+--------+ +--------+ +--------+
| colA | | colB | | colC |
+--------+ +--------+ +--------+
| 5 | | 5 | | 5 |
| 10 | | 15 | | 10 |
| 15 | +--------+ | 15 |
+--------+ +--------+
在上面的例子中,我在加入之后得到了这样的结果:
+--------+--------+--------+
| colA | colB | colC |
+--------+--------+--------+
| 5 | 5 | 5 |
| null | null | 10 |
| 15 | 15 | 15 |
| 10 | null | null |
+--------+--------+--------+
我的预期结果是这样的:
+--------+--------+--------+
| colA | colB | colC |
+--------+--------+--------+
| 5 | 5 | 5 |
| 10 | null | 10 |
| 15 | 15 | 15 |
+--------+--------+--------+
我加入的逻辑是先加入TableA
和TableB
,然后加入结果TableC
。在这种特定情况下,联接不起作用。连接可以尝试匹配从通过TableA
的列或从的列TableB
,但我不知道如何让它同时检查。
因为我是第一次加入TableA
and TableB
,所以里面没有匹配的值TableB
。当我尝试加入TableC
时TableB
,它也找不到匹配项,即使密钥存在于TableA
.
我最接近我想要的结果是使用这个查询:
SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.colA = TableB.colB
RIGHT OUTER JOIN TableC ON TableC.colC IN (TableA.colA, TableB.colB);
+------+ +------+ +------+ +------+------+------+
| colA | | colB | | colC | | colA | colB | colC |
+------+ +------+ +------+ +------+------+------+
| 5 | | 5 | | 5 | | 5 | 5 | 5 |
| 10 | | 15 | | 10 | --> | 10 | null | 10 |
| 15 | | 25 | | 15 | | 15 | 15 | 15 |
+------+ +------+ | 20 | | null | null | 20 |
+------+ +------+------+------+
预期结果:
+------+------+------+
| colA | colB | colC |
+------+------+------+
| 5 | 5 | 5 |
| 10 | null | 10 |
| 15 | 15 | 15 |
| null | null | 20 |
| null | 25 | null |
+------+------+------+
不幸的是,这不包括仅存在于最终连接表中TableA
或TableB
中的值,这就是我首先使用的原因FULL OUTER JOIN
。使用FULL OUTER JOIN
,我不能使用该IN
子句。有什么解决方案可以满足我的需求吗?
解决方案
这是一个演示完全三路完全外连接的版本。成功的查询将返回七行:
+------+ +------+ +------+ +------+------+------+ | 科尔A | | 科尔B | | 科尔C | | 科尔A | 科尔B | 科尔C | +------+ +------+ +------+ +------+------+------+ | 1 | | 2 | | 4 | | 1 | 空 | 空 | | 3 | | 3 | | 5 | --> | 空 | 2 | 空 | | 5 | | 6 | | 6 | | 3 | 3 | 空 | | 7 | | 7 | | 7 | | 空 | 空 | 4 | +------+ +------+ +------+ | 5 | 空 | 5 | | 空 | 6 | 6 | | 7 | 7 | 7 | +-----+------+------+
select ColA, ColB, ColC
from TableA
full join TableB
on ColA=ColB
full join TableC
on ColC=coalesce(ColA, ColB)
order by coalesce(ColA, ColB, ColC);
秘密在于coalesce
每个附加表的连接条件中的先前表键。
你可以在这里看到它的作用
推荐阅读
- elasticsearch - Elasticsearch 立即启动和停止
- angularjs - 在 $scope 函数中调用 $http.post 不起作用
- c# - 将数据库项目中的文件添加到 MSI
- laravel - 如何在 laravel 5.7 中从共享服务发送电子邮件
- html - Bootstrap 丢失布局打印肖像
- react-native - 如何在 react-native 上按需加载组件?
- python - tf 用不同的索引批量收集每个元素
- cassandra - 在不接触磁盘的情况下检查密钥是否存在
- angular - 通过 spy/karma 模拟服务类时无法读取未定义的属性“doc”
- r - R数据框 - 将月份列转置为12个单独的列