【问题标题】:Best way to do nested case statement logic in SQL Server在 SQL Server 中执行嵌套 case 语句逻辑的最佳方法
【发布时间】:2010-10-05 01:55:18
【问题描述】:

我正在编写一个 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)很好地缩进嵌套查询?
  • 感谢您教我一个更好的嵌套CASE WHEN的格式化方法
  • 在某些时候这肯定是有效和有用的,但总的来说,我喜欢让逻辑远离我的 SQL 查询。只是给后代的提示。

标签: sql sql-server sql-server-2005 select nested


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    选择合并( CASE WHEN 条件 1 THEN 计算 1 ELSE NULL END, CASE WHEN 条件 2 THEN 计算 2 ELSE NULL END, 等等... )

    【讨论】:

    • 很好,我刚刚测试了它以确保它短路,并惊讶地发现它确实如此。因此,如果条件 1 检查是否被零除,那么在条件 2 中执行它似乎是安全的。不确定这是否得到保证。
    • 一个问题是,如果您的一个案例合法地想要返回 NULL,那么它就不再可能了。
    • 这是一个很棒的技巧,但请记住,它的性能可能不如单独使用 CASE 语句。这在此处的“社区添加”部分“记录” - msdn.microsoft.com/en-us/library/ms190349.aspx。当我实施这个解决方案时,我的 DBA 只是放下了锤子......
    • 什么时候比一个案例陈述更好(@beach 的回答)?
    • 如何重命名此答案中的列。例如,如果我想将“calculation1”重命名为“CAL1”...从语法上讲怎么可能?
    【解决方案3】:

    我个人就是这样做的,保持嵌入的 CASE 表达式受到限制。我也会让 cmets 解释发生了什么。如果太复杂,就分解成函数。

    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
    

    【讨论】:

      【解决方案4】:

      下面是嵌套“复杂”案例语句的简单解决方案: --嵌套案例复杂表达式

      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
      

      只要确保每个 case 语句都有一个结束语句

      【讨论】:

      • 如果您希望他人阅读您的答案,您可能需要对其进行格式化。
      • 这对原始问题中使用的方法有何改进?
      【解决方案5】:

      将所有这些案例合二为一。


      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
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

          让我们想要执行案例的三个变量 a b c 。我们可以这样做:

          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,
          

          【讨论】:

            【解决方案8】:

            我经历了这个,发现所有答案都超级酷,但是想添加到@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 设为可选,因为它不是强制性的,它在许多情况下都非常有用。

            【讨论】:

              【解决方案9】:

              这个例子可能对你有所帮助,图片展示了当有 if 和多个内部 if 循环时 SQL case 语句的样子

              【讨论】:

              • 请放代码文本而不是截图,因为截图很难重复使用或确认。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-03-12
              • 1970-01-01
              • 1970-01-01
              • 2010-10-04
              • 1970-01-01
              • 1970-01-01
              • 2014-08-29
              相关资源
              最近更新 更多