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
换句话说,您不需要条件逻辑来指定每个季度。你可以只使用日期算法。
我无法解决这个问题。我想查看 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
换句话说,您不需要条件逻辑来指定每个季度。你可以只使用日期算法。