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

我目前正在写一个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 

你可以尝试某种联盟技巧,例如:

 SELECT COALESCE(
   CASE WHEN condition1 THEN calculation1 ELSE NULL END,
   CASE WHEN condition2 THEN calculation2 ELSE NULL END,
  等等...
 )

把所有这些情况都整合到一起。


 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 

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

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

我个人这样做,保持embeddedCASEexpression式的限制。 我还会发表评论来解释发生了什么事情。 如果太复杂,则将其分解为function。

 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 

一个用户定义的函数可能服务器更好,至less隐藏逻辑 – 特别是。 如果您需要在多个查询中执行此操作

下面是一个嵌套的“Complex”情况统计的简单解决scheme: – 嵌套情况复杂expression式

 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 

只要确保你有每个案例陈述的结束语句

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

让我们有三个variablesabc我们想要执行的情况。 我们可以做到这一点如下:

 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

  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成为可选项,因为它不是强制性的,这在许多情况下非常有用。