【问题标题】:What is a good way to make multiple full outer join?进行多个完全外连接的好方法是什么?
【发布时间】:2020-12-08 20:30:31
【问题描述】:

我想知道是否有人会知道一种优雅且可扩展的方法来完全外部联接多个表,因为我可能希望定期将新表添加到联接中?

现在我的方法包括将表 A 与表 B 完全连接,将结果存储为 cte,然后将 cte 完全连接到表 C,将结果存储为 cte2,将 cte2 完全连接到表 D...你明白了。

每次我想将另一个表添加到联接时创建一个新的 cte 并不是很实用,但是到目前为止我发现的所有其他解决方案都有相同的问题,在 ctes 或在 selects 中总是存在某种无限循环(比如 SELECT blabla FROM (SELECT blabla2 FROM..))。

有什么我不知道的方法可以帮助我执行这个多重完全连接而不陷入 ctes 的无限递归循环?

谢谢

编辑:抱歉,似乎还不够清楚 当我在一个查询中执行多个完全联接时,例如:

SELECT
    a.*, b.*, c.*
FROM
    tableA a
FULL JOIN
    tableB b
ON
    a.id = b.id
FULL JOIN
    tableC c
ON
    a.id = c.id

如果 id 存在于 tableB 和 tableC 但不存在于 tableA 中,我的结果将在应该有的地方创建两行,因为我将 b 连接到 a 和 c 连接到 a 而不是 b 连接到 c。这就是为什么我需要完全加入 a 和 b 到 c 的完全连接的结果。 因此,如果我说五个表而不是三个表,我需要将完全连接的结果完全连接的结果完全连接的结果完全连接的结果... x)

【问题讨论】:

  • 目前尚不清楚为什么答案不只是在一个 FROM 子句中多次出现 FULL OUTER JOIN,没有 CTE 等。也许您可以扩展示例以明确为什么这不是您想要的需要吗?
  • 用您正在使用的数据库标记您的问题。

标签: sql


【解决方案1】:

这个fiddle 说明了问题。

如果您希望表 B 和 C 中的行加入,您需要考虑数据可能来自表 B 而不是 A 的事实。最简单的可能是使用 COALESCE

因此,您的联接应如下所示:

SELECT a.*, b.*, c.*
FROM tableA a
FULL JOIN tableB b ON a.id = b.id
FULL JOIN tableC c ON COALESCE(a.id, b.id) = c.id
-- FULL JOIN tableD d ON COALESCE(a.id, b.id, c.id) = d.id
-- FULL JOIN tableE e ON COALESCE(a.id, b.id, c.id, d.id) = e.id

【讨论】:

  • "这意味着 a.id 为 NULL,这将阻止 tableC 加入。"这是一个全连接,如果 a.id 在 x 值上为空,但 B 和 C 都有一个对应于该 x 值的 id,它会创建两行
  • 哦,确实,对不起,我似乎有大脑滞后:-) 我的回答解决了这个问题。我会相应地更新介绍。
  • 解决方案本身有效,非常感谢:)
【解决方案2】:

大多数支持FULL JOIN 的数据库也支持USING,这是做你想做的最简单的方法:

SELECT *
FROM tableA a FULL JOIN
     tableB b
     USING (id) FULL JOIN
     tableC c
     USING (id);

USING 的语义意味着仅使用非NULL 值,如果这样的值可用的话。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-19
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2019-01-12
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多