我正在编写一个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
Chris KL.. 174
你可以试试某种COALESCE技巧,例如:
SELECT COALESCE( CASE WHEN condition1 THEN calculation1 ELSE NULL END, CASE WHEN condition2 THEN calculation2 ELSE NULL END, etc... )
一个问题是如果你的一个案例合法地想要返回NULL,那就不再可能了. (11认同)
这是一个很好的技巧,但请记住,它可能不如单独使用CASE语句那样好.这是在"社区添加"部分中"记录"的 - http://msdn.microsoft.com/en-us/library/ms190349.aspx.当我实施这个解决方案时,我的DBA只是放下了锤子...... (7认同)
Deejers.. 82
将所有这些案例包装成一个.
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
ssingh.. 27
您可以结合多个条件来避免这种情况:
CASE WHEN condition1 = true AND condition2 = true THEN calculation1 WHEN condition1 = true AND condition2 = false ELSE 'what so ever' END,
beach.. 18
我个人这样做,保持嵌入式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
只需确保每个案例陈述都有一个结束语句
你可以试试某种COALESCE技巧,例如:
SELECT COALESCE( CASE WHEN condition1 THEN calculation1 ELSE NULL END, CASE WHEN condition2 THEN calculation2 ELSE NULL END, etc... )
将所有这些案例包装成一个.
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,
我个人这样做,保持嵌入式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
这是嵌套的"复杂"案例陈述的简单解决方案: - 嵌套案例复杂表达式
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
只需确保每个案例陈述都有一个结束语句
用户定义的函数可以更好地服务,至少隐藏逻辑 - 尤其是.如果您需要在多个查询中执行此操作
我们可以将多个条件组合在一起以降低性能开销.
让我们想要执行三个变量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,