【问题标题】:Multiple CASEs in WHERE Clause with ELSE带有 ELSE 的 WHERE 子句中的多个 CASE
【发布时间】:2014-05-13 02:07:11
【问题描述】:

我正在尝试在类似这样的 WHERE 子句中编写 CASE 语句。 我的问题是,最后我想说ELSE CalendarQuarter IN (@Q1,@Q2,@Q3,@Q4)。因此,如果这些条件都不满足,请执行其他操作。我不知道如何添加这个ELSE 语句。

AND CalendarQuarter in
(
    /*March, June, Sep 2010 Metcard*/
    (CASE WHEN DATEPART(yy,@year_end) = 2010 
        AND @ticketing_system = 'metcard' 
        AND DATEPART(mm,@year_end) IN (3,6,9)  THEN @Q1  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2010
        AND @ticketing_system = 'metcard' 
        AND DATEPART(mm,@year_end) IN (3,6)  THEN @Q2  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2010
        AND @ticketing_system = 'metcard' 
        AND DATEPART(mm,@year_end) IN (3)  THEN @Q3  END),

    /*March, June, Sep 2010 Metcard/Myki*/  
    (CASE WHEN DATEPART(yy,@year_end) = 2010 
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (9,6,3)  THEN @Q4  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2010 
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (9,6)  THEN @Q3  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2010 
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (9)  THEN @Q2  END),

    /*March, June, Sep 2013 Metcard/Myki*/
    (CASE WHEN DATEPART(yy,@year_end) = 2013 
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (3,6,9)  THEN @Q1  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2013
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (3,6)  THEN @Q2  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2013
        AND @ticketing_system = 'metcard/myki' 
        AND DATEPART(mm,@year_end) IN (3)  THEN @Q3  END),

    /*March, June, Sep 2013 Myki*/  
    (CASE WHEN DATEPART(yy,@year_end) = 2013 
        AND @ticketing_system = 'myki' 
        AND DATEPART(mm,@year_end) IN (9,6,3)  THEN @Q4  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2013 
        AND @ticketing_system = 'myki' 
        AND DATEPART(mm,@year_end) IN (9,6)  THEN @Q3  END),
    (CASE WHEN DATEPART(yy,@year_end) = 2013 
        AND @ticketing_system = 'myki' 
        AND DATEPART(mm,@year_end) IN (9)  THEN @Q2  END),

    /*ELSE....IN (@Q1,@Q2,@Q3,@Q4)*/

)

【问题讨论】:

    标签: sql sql-server tsql case


    【解决方案1】:

    我没有足够的声望给你的帖子添加评论,但听起来你想添加另一个案例陈述。 ELSE 不应该有任何条件,它用于捕获与它所附加的 case 语句中的任何条件不匹配的所有内容。

    例如 foo 列可以包含 1、2、3 或 4,我们希望将列分别设置为 a、b、c 或 c。我们有以下case语句

    CASE
        WHEN foo = 1
            THEN 'a'
        WHEN foo = 2
            THEN 'b'
        ELSE 'c'
    END
    

    我们不需要为 3 或 4 添加 case,因为它们不匹配 1 或 2,所以它们将由 else 处理,将它们设置为 c。

    如果您尝试在 else 语句中添加另一个条件,您可以在 else 中使用另一个 case 语句。在这种情况下,我们希望将 foo 3 或 4 的值转换为 x 或 y。

    CASE
        WHEN foo = 1
            THEN 'a'
        WHEN foo = 2
            THEN 'b'
        ELSE CASE
                WHEN foo = 3
                    THEN 'x'
                WHEN foo = 4
                    THEN 'y'
                ELSE NULL
            END
    END
    

    当然,你可以使用任何你想要的值,你不需要在条件中评估单个列。

    编辑:我使用您的案例陈述创建了一个示例。它在您的 ELSE 中有第二个 case 语句,允许您向 else 添加条件。

    AND CalendarQuarter IN
                        (
                        CASE 
                            /*March, June, Sep 2010 Metcard*/
                            WHEN DATEPART(yy,@year_end) = 2010 
                                            AND @ticketing_system = 'metcard' 
                                            AND DATEPART(mm,@year_end) IN (3,6,9)  
                                THEN @Q1
                            WHEN DATEPART(yy,@year_end) = 2010
                                            AND @ticketing_system = 'metcard' 
                                            AND DATEPART(mm,@year_end) IN (3,6)  
                                THEN @Q2
                            WHEN DATEPART(yy,@year_end) = 2010
                                            AND @ticketing_system = 'metcard' 
                                            AND DATEPART(mm,@year_end) IN (3)  
                                THEN @Q3
    
                            /*March, June, Sep 2013 Metcard/Myki*/
                            CASE WHEN DATEPART(yy,@year_end) = 2010 
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (9,6,3)  
                                THEN @Q4
                            WHEN DATEPART(yy,@year_end) = 2010 
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (9,6)  
                                THEN @Q3
                            WHEN DATEPART(yy,@year_end) = 2010 
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (9)  
                                THEN @Q2
    
                            /*March, June, Sep 2013 Metcard/Myki*/
                            WHEN DATEPART(yy,@year_end) = 2013 
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (3,6,9)  
                                THEN @Q1
                            WHEN DATEPART(yy,@year_end) = 2013
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (3,6)  
                                THEN @Q2
                            WHEN DATEPART(yy,@year_end) = 2013
                                            AND @ticketing_system = 'metcard/myki' 
                                            AND DATEPART(mm,@year_end) IN (3)  
                                THEN @Q3
    
                            /*March, June, Sep 2013 Myki*/ 
                            WHEN DATEPART(yy,@year_end) = 2013 
                                            AND @ticketing_system = 'myki' 
                                            AND DATEPART(mm,@year_end) IN (9,6,3)  
                                THEN @Q4
                            WHEN DATEPART(yy,@year_end) = 2013 
                                            AND @ticketing_system = 'myki' 
                                            AND DATEPART(mm,@year_end) IN (9,6)  
                                THEN @Q3
                            WHEN DATEPART(yy,@year_end) = 2013 
                                            AND @ticketing_system = 'myki' 
                                            AND DATEPART(mm,@year_end) IN (9)  
                                THEN @Q2
    
                            ELSE CASE
                                    WHEN [YOUR CONDITION HERE] IN (@Q1,@Q2,@Q3,@Q4)
                                        THEN [SOME RESULT]
                                    END
                        END
                        )
    

    只要满足一个条件,上面的语句就会返回。另一种方法是使用您原来的 case 语句,但不是使用 else,而是使用与上述条件相反的条件。例如

    CASE 
        WHEN DATEPART(yy,@year_end) = 2013
            THEN CASE 
                    WHEN @ticketing_system = 'myki' 
                        THEN CASE
                                WHEN DATEPART(mm,@year_end) NOT IN (9,6,3)
                                    THEN (@Q1,@Q2,@Q3,@Q4)
                            END
                    WHEN @ticketing_system = 'metcard/myki' 
                        THEN CASE
                                WHEN DATEPART(mm,@year_end) NOT IN (3,6,9)
                                    THEN (@Q1,@Q2,@Q3,@Q4)
                            END
                 END
        WHEN DATEPART(yy,@year_end) = 2010
            THEN CASE
                    WHEN @ticketing_system = 'metcard/myki'
                        THEN CASE
                                WHEN DATEPART(mm,@year_end) NOT IN (9,6,3)
                                    THEN (@Q1,@Q2,@Q3,@Q4)
                            END
                    WHEN @ticketing_system = 'metcard' 
                        THEN CASE
                                WHEN DATEPART(mm,@year_end) NOT IN (3,6,9)
                                    THEN (@Q1,@Q2,@Q3,@Q4)
                             END
                END
    END
    

    【讨论】:

    • 使用此代码,一旦发现其中一个语句为真,它不会停止吗?例如,如果第一个陈述是真的,那么我仍然希望它评估第二个陈述,因为它可能也是真的。
    • 你是对的,这只会匹配一条记录。我可以建议的最简单的解决方案是编写一个最终的 case 语句,它与执行它的 case 语句相反。或者,您可以将 case 语句的结果用作查询中的一列,然后将其包装在选择测试中是否为空。我已经编辑了我的答案,以添加一个相反的 case 语句示例。我想我得到了每个条件,但你可能想快速检查一下。
    【解决方案2】:

    我建议您避免使用 case 子句并尝试使用:

    WHERE (DATEPART(yy,@year_end) = 2010
    AND @ticketing_system         = 'metcard'
    AND DATEPART(mm,@year_end)   IN (3,6,9)
    AND CalendarQuarter          IN (@Q1))
    OR 
    (DATEPART(yy,@year_end)    = 2010
    AND @ticketing_system         = 'metcard'
    AND DATEPART(mm,@year_end)   IN (3,6)
    AND CalendarQuarter          IN (@Q2))
    ..................................
    OR 
    (DATEPART(yy,@year_end)    = 2013
    AND @ticketing_system         = 'myki'
    AND DATEPART(mm,@year_end)   IN (9)
    AND CalendarQuarter          IN(@Q2) )
    OR 
    (CalendarQuarter          IN (@Q1,@Q2,@Q3,@Q4))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      相关资源
      最近更新 更多