如何根据case语句在连接多个表时选择一行

Posted

技术标签:

【中文标题】如何根据case语句在连接多个表时选择一行【英文标题】:how to select one row in joining multiple tables based on a case statement 【发布时间】:2016-07-01 18:42:13 【问题描述】:

我有 Table A 引用 Table BTable B 可能在 A 中的每条记录都有一个或多个条目。在 B 中,我有一列作为状态。我想根据下面的给定条件选择一行。考虑我在Table B 中有 3 个条目

如果任一行的状态为 OA 或 OB,则选择该行 如果状态不是 OA 或 OB,则选择任意一行

我的查询

--lot more table joins already here
LEFT JOIN(
SELECT CASE WHEN EXISTS
      ( SELECT 1 FROM A a1 INNER JOIN B b1 ON a1.id = b1.id      
        WHERE b1.status in ('OA','OB'))
        THEN (SELECT b1.rcid FROM A a1 INNER JOIN B b1 ON a1.id = b1.id      
        WHERE b1.status in ('OA','OB'))
        ELSE
        SELECT TOP 1 b2.rcid FROM A a2 INNER JOIN B b2 ON a2.id = b2.id
        END
      ))Z on z.id=b2.id --again join with table for b2.rcid

这是正确的方法吗?会不会对性能有影响?真的想在这里强调一下,实际上我必须加入近 10 个表,其中 5 个表将有 100 000 多条记录。

【问题讨论】:

【参考方案1】:
cross/outer apply (
    select top 1 status
    from B b
    where b.id = a.id
    order by case when status in ('OA', 'OB') then 1 else 2 end, status
)

inner/left join (
    select
        id,
        case min(case when status in ('OA', 'OB') then 1 else 2 end)
            when 1 then min(cast when status in ('OA', 'OB') then status end)
            when 2 then min(status)
        end
    from B
    group by id
) b on b.id = a.id

【讨论】:

第一个解决方案对我有帮助。但是另一个问题是,正如我之前提到的,我的表 A 可能不包含在“APPLY”之前加入的表的行,所以这个交叉应用跳过了那些,但我也需要表 A 中的那些记录。 @Satheesh 使用outer apply 是的,我试过了,它的工作原理,但是否建议使用外部应用。根据链接 ***.com/questions/6726696/… 。外部应用是否会对性能产生影响,因为我正在查询一个包含超过 lac 记录的表,这将至少拉出 10K @Satheesh 这将取决于很多事情。您必须尝试一下,尽管我认为在您的情况下,如果有的话,这并不重要。

以上是关于如何根据case语句在连接多个表时选择一行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 case 语句中的函数返回值以选择每个函数的 MAX?

连接字符串,基于 Case 语句

ORA-00904 使用 CASE 语句更新表时标识符无效

case when用法sql

switch case语句总执行第一个case

用于检查 NULLS 和不存在记录的 SQL Case 语句