在SQL Server中执行嵌套case语句逻辑的最佳方法


185

我正在写一个SQL查询,其中需要根据很多条件来计算返回的一些列。

我目前正在使用嵌套的case语句,但是它变得凌乱。有没有更好(更有条理和/或更易读)的方法?

(我正在使用Microsoft SQL Server,2005)


一个简化的例子:

SELECT
    col1,
    col2,
    col3,
    CASE
        WHEN condition 
        THEN
            CASE
                WHEN condition1 
                THEN
                    CASE 
                        WHEN condition2
                        THEN calculation1
                        ELSE calculation2
                    END
                ELSE
                    CASE 
                        WHEN condition2
                        THEN calculation3
                        ELSE calculation4
                    END
            END
        ELSE 
            CASE 
                WHEN condition1 
                THEN 
                    CASE
                        WHEN condition2 
                        THEN calculation5
                        ELSE calculation6
                    END
                ELSE
                    CASE
                        WHEN condition2 
                        THEN calculation7
                        ELSE calculation8
                    END
            END            
    END AS 'calculatedcol1',
    col4,
    col5 -- etc
FROM table

嗨,您是否使用工具(如SQLinForm)很好地缩进了嵌套查询?
Guido

感谢你教我一个更好的方法格式化嵌套CASE WHEN
Simon1979

当然,有时候这样做会很有效并且很有帮助,但是总的来说,我希望逻辑与SQL查询保持隔离。只是后代的一个提示。
tschwab

Answers:


187

您可以尝试某种COALESCE技巧,例如:

选择粗粉(
  当condition1 THEN计算1 ELSE NULL END时的情况,
  当condition2 THEN计算2 ELSE NULL END时的情况,
  等等...
)

很好,我刚刚进行测试以确保其短路,并惊讶地发现确实如此。因此,如果condition1检查是否除以零,则在condition2中执行此操作似乎是安全的。不确定是否可以保证。
凯德·鲁

12
一个陷阱是,如果您的情况之一合法地想要返回NULL,则不再可能。
克里斯KL,2009年

7
这是一个绝妙的技巧,但请记住,它可能不如单独使用CASE语句那样好。这是在“社区添加”部分的“文档”中-msdn.microsoft.com/en-us/library/ms190349.aspx。当我实施此解决方案时,我的DBA只是放下了锤子……
shanabus

什么时候比仅案例说明(@beach的答案)更好?
罗尼·奥弗比

如何在此答案中重命名列..例如,如果我想将“ calculation1”重命名为“ CAL1” ...从语法上讲,这怎么可能?
重生

87

将所有这些案例合并为一个。


SELECT
    col1,
    col2,
    col3,
    CASE
        WHEN condition1 THEN calculation1 
        WHEN condition2 THEN calculation2
        WHEN condition3 THEN calculation3
        WHEN condition4 THEN calculation4
        WHEN condition5 THEN calculation5
        ELSE NULL         
    END AS 'calculatedcol1',
    col4,
    col5 -- etc
FROM table

30

您可以组合多个条件来避免这种情况:

CASE WHEN condition1 = true AND condition2 = true THEN calculation1 
     WHEN condition1 = true AND condition2 = false 
     ELSE 'what so ever' END,

21

我本人就是这样做的,同时保持嵌入式CASE表达式的约束。我也会在评论中说明发生了什么。如果过于复杂,请将其分解为功能。

SELECT
    col1,
    col2,
    col3,
    CASE WHEN condition THEN
      CASE WHEN condition1 THEN
        CASE WHEN condition2 THEN calculation1
        ELSE calculation2 END
      ELSE
        CASE WHEN condition2 THEN calculation3
        ELSE calculation4 END
      END
    ELSE CASE WHEN condition1 THEN 
      CASE WHEN condition2 THEN calculation5
      ELSE calculation6 END
    ELSE CASE WHEN condition2 THEN calculation7
         ELSE calculation8 END
    END AS 'calculatedcol1',
    col4,
    col5 -- etc
FROM table

11

这是嵌套“复杂”案例陈述的简单解决方案:-嵌套案例复杂表达式

select  datediff(dd,Invdate,'2009/01/31')+1 as DaysOld, 
    case when datediff(dd,Invdate,'2009/01/31')+1 >150 then 6 else
        case when datediff(dd,Invdate,'2009/01/31')+1 >120 then 5 else 
            case when datediff(dd,Invdate,'2009/01/31')+1 >90 then 4 else 
                case when datediff(dd,Invdate,'2009/01/31')+1 >60 then 3 else 
                    case when datediff(dd,Invdate,'2009/01/31')+1 >30 then 2 else 
                        case when datediff(dd,Invdate,'2009/01/31')+1 >30 then 1 end 
                    end
                end
            end
        end
    end as Bucket
from rm20090131atb

只要确保每个案例都有一个结尾声明


5
如果您希望其他人阅读答案,则可能需要设置其格式。
IsmailS 2010年

6

我们可以将多个条件组合在一起以减少性能开销。

让我们对三个变量abc进行案例分析。我们可以这样做,如下所示:

CASE WHEN a = 1 AND b = 1 AND c = 1 THEN '1'
     WHEN a = 0 AND b = 0 AND c = 1 THEN '0'
ELSE '0' END,

5

用户定义的函数可能会更好地处理服务器,至少要隐藏逻辑-尤其是。如果您需要在多个查询中执行此操作


2

我经历了这个,发现所有答案都很棒,但是想添加到@deejers给出的答案

    SELECT
    col1,
    col2,
    col3,
    CASE
        WHEN condition1 THEN calculation1 
        WHEN condition2 THEN calculation2
        WHEN condition3 THEN calculation3
        WHEN condition4 THEN calculation4
        WHEN condition5 THEN calculation5         
    END AS 'calculatedcol1',
    col4,
    col5 -- etc
FROM table

您可以将ELSE设为可选,因为它不是强制性的,在许多情况下非常有用。


2

该示例可能会对您有所帮助,该图显示了当存在if和多个内部if循环时,SQL case语句的外观

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.