Sql 如果一个或多个表中可能缺少一个键,是否可以在同一个键上联接三个表?
我使用相同的主键将三个表连接在一起,但不能保证所有值都存在于所有三个表中,我希望每个值都最终连接在一起 例如,有一个Sql 如果一个或多个表中可能缺少一个键,是否可以在同一个键上联接三个表?,sql,postgresql,join,Sql,Postgresql,Join,我使用相同的主键将三个表连接在一起,但不能保证所有值都存在于所有三个表中,我希望每个值都最终连接在一起 例如,有一个TableA,TableB,和TableC,每个都只有一列(我们将这些列称为colA,colB,和colC)。值10出现在表A和表C中,但不在表B中 SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.colA = TableB.colB FULL OUTER JOIN TableC
TableA
,TableB
,和TableC
,每个都只有一列(我们将这些列称为colA
,colB
,和colC
)。值10
出现在表A
和表C
中,但不在表B
中
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
和TableB
,所以TableB
中没有匹配的值。当我尝试在TableB
上加入TableC
时,它也找不到匹配项,即使键存在于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 |
+------+------+------+
不幸的是,这不包括在最终联接表中的表A
或表B
中仅存在的值,这就是我首先使用完全外部联接的原因。有了完全外部联接
,我不能在
子句中使用。有没有一个解决方案可以满足我的需求
DB Fiddle:我想你想要左加入
s:
SELECT *
FROM TableA LEFT OUTER JOIN
TableB
ON TableA.colA = TableB.colB LEFT JOIN
TableC
ON TableA.colA = TableC.colC;
以下是一个。此连接组合将为您提供所需的结果:
select *
from (SELECT *
FROM TableC
full outer join TableB on TableC.colC = TableB.colB ) t1
left join TableA on t1.colc = TableA.colA or t1.colB = TableA.colA
这是一个不同的加入你需要的。下面是另一个例子:
select * from
(SELECT *
FROM TableC
full outer join TableB on TableC.colC = TableB.colB ) t1
full join TableA on t1.colc = TableA.colA
下面是一个演示完全三向完全外部联接的版本。成功的查询将返回七行:
+------+ +------+ +------+ +------+------+------+
| colA | | colB | | colC | | colA | colB | colC |
+------+ +------+ +------+ +------+------+------+
| 1 | | 2 | | 4 | | 1 | null | null |
| 3 | | 3 | | 5 | --> | null | 2 | null |
| 5 | | 6 | | 6 | | 3 | 3 | null |
| 7 | | 7 | | 7 | | null | null | 4 |
+------+ +------+ +------+ | 5 | null | 5 |
| null | 6 | 6 |
| 7 | 7 | 7 |
+------+------+------+
秘密在于在每个附加表的联接条件中,合并
先前的表键
您可以在操作中看到它,它没有给出预期的结果,这是指向我的原始小提琴的链接。@user-2147482428。我认为那是小提琴环境中的一个缺陷。它需要点击“fork”(一个明显的名字,叹气)来获得一个新的链接。我添加了一个显示代码工作的链接。我可以通过在表a
中包含一个不在表B
或表C
中的值来打破这一点:在这种情况下,是否可以创建这样一个不会从表a
中删除值的查询?Hi@user-2147482428我添加了另一个您可以检查的查询。干杯你实际上没有清楚地解释你想要什么。你描述了你想要的东西的一些方面。你的例子是什么(为什么“有些像”&不完全像?)?当给出业务关系(ship)/关联或表(基或查询结果)时,请说明其中的一行根据其列值对业务状况的说明。了解外部联接返回的内容:返回时的左/右联接返回时的内部联接行并集所有不匹配的左/右表行均以null扩展。完全连接返回行上的内部连接并将所有不匹配的左、右表行扩展为null。始终知道作为外部联接的一部分,您需要什么样的内部联接。
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);