【问题标题】:Passing table for JOIN using CASE WHEN statement使用 CASE WHEN 语句为 JOIN 传递表
【发布时间】:2021-02-13 09:31:36
【问题描述】:

我正在尝试使用 CASE WHEN 语句来确定将哪个表用于 JOIN 的后半部分。例如,有 3 个表:TableA、TableB、TableC。

SELECT a.column1, b.column2
FROM
TableA as a
FULL OUTER JOIN
CASE WHEN condition1 THEN TableB as b
ELSE TableC as b
END
ON a.ID = b.ID

Example:

TableA
ID: 1 2 3
Column1: 10 20 30

TableB
ID: 1 2 3
Column2: 100 200 300

TableC
ID: 1 2 3
Column2: 1000 2000 3000

-- Result 1 --> CASE WHEN statement is true, TableA and TableB are joined

Column1: 10 20 30
Column2: 100 200 300

-- Result 2 --> CASE WHEN statement is false, TableA and TableC are joined

Column1: 10 20 30
Column2: 1000 2000 3000
 

我一直想使用 TableA 进行连接,但是根据特定条件,我想加入 TableB 或 TableC。无论使用哪个第二个表进行连接,我都希望它被引用为“b”,以便 ON 条件可以只使用 b.ID,而 SELECT 语句将始终使用 b.column2

【问题讨论】:

  • 请提供样本数据和期望的结果。 SQL 查询以SELECT 开头,而不是TableA,因此您的代码不是有效的查询。
  • (1) 在同一个 from 子句中不能有两个具有相同别名的表,因此您的问题的最后一部分是不可能的 (2) 请提供示例数据和所需结果;你所要求的仍然可能是可行的,虽然不是你想象的那样。
  • 添加了一个例子!

标签: sql left-join inner-join


【解决方案1】:

您可以left join 两次。条件转到每个连接的on 子句:

select a.col1, coalesce(b.col2, c.col2) as col2
from tablea a
left join tableb b 
    on  b.id = a.id
    and (condition)      -- condition is met
left join tablec c 
    on  c.id = a.id   
    and not (condition)  -- condition is not met

【讨论】:

  • 我正在使用的文件非常大,生成 TableA、TableB 和 TableC 需要相当长的时间,所以我希望避免在不需要时查询 TableB 或 TableC .如果我的操作正确,上面的代码总是会查询 TableB 和 TableC,不管它们是否被使用,对吧?想知道是否有办法只查询我需要的 2 个表。
  • @Matt:数据库将决定是否应该查询哪个表。不要过早优化。根据您的实际用例调整查询,然后对其进行测试,看看会发生什么。
【解决方案2】:

可以将包含条件的两张表合并,从而得到其中一个的行:

SELECT a.column1, b.column2
FROM TableA a
FULL OUTER JOIN
(
  SELECT id, column2 FROM TableB WHERE <condition>
  UNION ALL
  SELECT id, column2 FROM TableC WHERE NOT <condition>
) b ON a.id = b.id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-10
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多