Best way to do nested case statement logic in SQL Server
我正在写一个SQL查询,其中需要根据很多条件来计算返回的一些列。
我目前正在使用嵌套的case语句,但是它变得凌乱。 有没有更好(更有条理和/或更易读)的方法?
(我正在使用Microsoft SQL Server,2005)
一个简化的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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 |
您可以尝试某种COALESCE技巧,例如:
1 2 3 4 5 | SELECT COALESCE( CASE WHEN condition1 THEN calculation1 ELSE NULL END, CASE WHEN condition2 THEN calculation2 ELSE NULL END, etc... ) |
将所有这些案例合并为一个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 |
您可以组合多个条件来避免这种情况:
1 2 3 | CASE WHEN condition1 = TRUE AND condition2 = TRUE THEN calculation1 WHEN condition1 = TRUE AND condition2 = FALSE ELSE 'what so ever' END, |
我本人就是这样做的,同时保持嵌入式CASE表达式的约束。我也会在评论中说明发生了什么。如果过于复杂,请将其分解为功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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 |
这是嵌套"复杂"案例陈述的简单解决方案:
-嵌套案例复杂表达
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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 |
只要确保每个案例都有一个结尾声明
我们可以将多个条件组合在一起以减少性能开销。
让我们对三个变量a b c进行案例分析。我们可以这样做,如下所示:
1 2 3 | 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, |
用户定义的函数可能会更好地处理服务器,至少要隐藏逻辑-尤其是。如果您需要在多个查询中执行此操作
我经历了这个,发现所有答案都很棒,但是想添加@deejers给出的答案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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设为可选,因为它不是强制性的,在许多情况下非常有用。
此示例可能会为您提供帮助,该图显示了在存在if和多个内部if循环时SQL case语句的外观