WHERE 子句中的 CASE 语句 SQL Server

问题描述

我很难解决这个问题。我想查看 Date_Received 的财政季度。当@ReviewPeriodQuarter = 1 时,我想要 Date_Received 月份 10、11、12。如果@ReviewPeriodQuarter = 2 那么我想要 Date_Received 月份 1,2,3 等。sql Server 不喜欢这个的 BETWEEN 部分。谢谢

DECLARE @ReviewPeriodQuarter Int

SELECT * FROM Table
WHERE
        MONTH(Date_Received) =
        CASE 
            WHEN @ReviewPeriodQuarter = 1 THEN BETWEEN 10 AND 12 
            WHEN @ReviewPeriodQuarter = 2 THEN BETWEEN 1 AND 3 
            WHEN @ReviewPeriodQuarter = 3 THEN BETWEEN 4 AND 6 
            WHEN @ReviewPeriodQuarter = 4 THEN BETWEEN 7 AND 9 
        END 

解决方法

个人而言,我会将范围完全移到 SELECT 之外,然后只使用简单的 WHERE

DECLARE @MonthStart int,@MonthEnd int;

SELECT @MonthStart = CASE @ReviewPeriodQuarter WHEN 1 THEN 10,WHEN 2 THEN 1
                                               WHEN 3 THEN 4
                                               WHEN 4 THEN 7
                     END,@MonthEnd = CASE @ReviewPeriodQuarter WHEN 1 THEN 12,WHEN 2 THEN 3
                                             WHEN 3 THEN 6
                                             WHEN 4 THEN 9
                   END;

SELECT *
FROM dbo.[Table]
WHERE MONTH(Date_Received) BETWEEN @MonthStart AND @MonthEnd;

请注意,由于在 MONTH(Date_Received) 中使用了 WHERE,但这仍然不是 SARGable。我必须承认,无论年份如何,都需要表中特定月份的行有点奇怪。如果那您的真正需求,那么您最好“投资”一个可以JOIN的日历表,然后在日历表的{{ 1}} 列;哪个是 SARGable。

,

您可以使用更多参数(如 Larnu)来实现,也可以使用原始方法但进行了调整

DECLARE @ReviewPeriodQuarter INT

SELECT *
FROM Table
WHERE MONTH(Date_Received) BETWEEN 
CASE 
    WHEN @ReviewPeriodQuarter = 1 THEN 10
    WHEN @ReviewPeriodQuarter = 2 THEN 1
    WHEN @ReviewPeriodQuarter = 3 THEN 4
    WHEN @ReviewPeriodQuarter = 4 THEN 7
END 
AND 
CASE 
    WHEN @ReviewPeriodQuarter = 1 THEN 12
    WHEN @ReviewPeriodQuarter = 2 THEN 3
    WHEN @ReviewPeriodQuarter = 3 THEN 6
    WHEN @ReviewPeriodQuarter = 4 THEN 9
END