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);