WHERE 子句 SQL 服务器中的 CASE 语句

CASE Statement in WHERE Clause SQL Server

我无法解决这个问题。我想查看 Date_Received 的财政季度。当@ReviewPeriodQuarter = 1 时,我想要 Date_Received 个月 10、11、12。如果@ReviewPeriodQuarter = 2 那么我想要 Date_Received 月 1、2、3 等等。SQL 服务器不喜欢其中的 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;

请注意,由于在 WHERE 中使用了 MONTH(Date_Received),因此这仍然不是 SARGable。我必须承认,无论年份如何,特定月份都需要 table 中的行有点奇怪。如果 你的真正要求,你可能最好“投资”日历 Table 你可以 JOIN ,然后只需要一个 WHERE 在日历 table 的 CalendarMonth 列上; 是 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 

使用values()怎么样?

SELECT *
FROM Table t JOIN
     (VALUES (1, 10, 12),
             (2, 1, 3),
             (3, 4, 6),
             (4, 7, 9)
     ) v(ReviewPeriodQuarter, lo, hi)
     ON MONTH(t.Date_Received) BETWEEN v.lo AND v.hi AND
        v.ReviewPeriodQuarter = @ReviewPeriodQuarter;

或者更简单:

WHERE DATEPART(quarter, DATEADD(MONTH, -3, t.Date_Received)) = @ReviewPeriodQuarter

换句话说,您不需要条件逻辑来指定每个季度。你可以只使用日期算法。