【问题标题】:SQL conditional join to multiple tables in one shot一次对多个表进行 SQL 条件连接
【发布时间】:2016-05-04 10:28:14
【问题描述】:

我想对三个表进行条件连接。左连接表 B,如果缺少键,则连接到表 C。

+------+--+------+-------------+--+------+-------------+
| A.id |  | B.id | B.OtherFish |  | C.id | C.OtherFish |
+------+--+------+-------------+--+------+-------------+
|    1 |  |    1 | B1          |  |    1 | C1          |
|    2 |  |      |             |  |    2 | C2          |
|    3 |  |    3 | B3          |  |    3 | C3          |
|    4 |  |      |             |  |    4 | C4          |
|    5 |  |    5 | B5          |  |      |             |
|    6 |  |    6 | B6          |  |    6 | C6          |
+------+--+------+-------------+--+------+-------------+

B 中没有匹配的 2 和 4 键,C 中也没有 5 的键。 预期结果:

+------+-----------+
| A.id | OtherFish |
+------+-----------+
|    1 | B1        |
|    2 | C2        |
|    3 | B3        |
|    4 | C4        |
|    5 | B5        |
|    6 | B6        |
+------+-----------+

我使用的查询是:

select 
A.id 
,coalesce(B.id,C.id) 
,coalesce(B.OtherFish,C.OtherFish)
from A
left join B
on A.id=B.id
left join C
on A.id=C.id

该方法的缺点是我必须通过来自不同表的所有我需要的列使用合并。如果表中有一百列,这很烦人。 最好合并整个别名,例如coalesce(B,C)

是否可以像这样一次性完成:

left join B
on A.id=B.id
left join C
on A.id=(case when B.id is null then C.id end)

这样在 C.id 中我将拥有所有好的数据而不需要合并所有列?

【问题讨论】:

  • 添加一些示例表数据和预期的结果。
  • 你用的是什么关系型数据库?
  • COALESCE 有什么问题?
  • 我同意,更难理解.. 正如我所说,我认为合并没有任何问题:) @RafalZiolkowski
  • 如果表中有“数百列”,那么这可能是您的问题,而不是使用COALESCE。如果您的建议是允许且有意义的,那么这意味着您有许多具有相同结构的表,这表明违反了规范化规则。换句话说:如果BC 非常相似,您可以在连接中交换它们,为什么它们不是带有鉴别器列的单个表?

标签: sql sql-server sql-server-2008 join


【解决方案1】:

虽然我看不出 COALESCE 有什么问题,但您可以尝试使用 UNION ,如下所示:

SELECT a.id,t.OtherFish
FROM A
LEFT JOIN(SELECT b.id,b.otherFish FROM b
          UNION ALL
          SELECT c.id,c.otherFish FROM C 
          where c.id NOT EXISTS(SELECT 1 FROM b bb WHERE bb.id = c.id)) t
ON(a.id = t.id)

【讨论】:

  • @GordonLinoff 嗯,我不明白为什么。
  • 感谢这种方法。然而令人失望的是,没有提出更简单的解决方案。与数学相比,我想要将别名放在括号外以避免合并数百列。
  • 抱歉,我怀疑还有其他解决方案。一般来说,coalesce 是解决这个问题的正确方法,尽管这个查询可能会稍微快一些。我从未听说过任何其他方法来解决这个问题.. 这不是数学。 @PrzemyslawRemin
猜你喜欢
  • 1970-01-01
  • 2016-11-13
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 2014-12-31
相关资源
最近更新 更多