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

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语句的外观

enter image description here