【发布时间】:2021-12-08 18:05:02
【问题描述】:
数据:
DECLARE @Dates TABLE
(
[MyDate] DATE
, [WkStart] DATE
, [WkEnd] DATE
) ;
INSERT INTO @Dates
SELECT '2021-10-03'
, '2021-09-27'
, '2021-10-03'
UNION
SELECT '2021-10-21'
, '2021-10-18'
, '2021-10-24'
UNION ALL
SELECT '2021-10-23'
, '2021-10-18'
, '2021-10-24'
UNION
SELECT '2021-10-27'
, '2021-10-25'
, '2021-10-31' ;
目标:
输出 2 个字段。第一个 = 日期字段,第二个 = 位字段。日期字段将包含每条记录的 [WkStart] 和 [WkEnd] 之间的所有日期。当 [MyDate] 等于第一个字段的值时,位字段将为真。桌子很大,所以性能很重要。当 2+ [MyDate] 值属于同一周范围时,该周的日期不应重复。
预期输出:
我的尝试:
; WITH recrCTE AS
(
SELECT CAST ( [WkStart] AS DATETIME ) AS [DateVal]
, [WkEnd]
, [MyDate]
FROM @Dates
UNION ALL
SELECT [DateVal] + 1
, [WkEnd]
, [MyDate]
FROM recrCTE
WHERE [DateVal] + 1 <= [WkEnd]
)
SELECT [DateVal]
, IIF ( [MyDate] = [DateVal], 1, 0 ) AS [isMyDate]
FROM recrCTE
ORDER BY [DateVal]
OPTION ( MAXRECURSION 0 ) ;
当前输出:
这个解决方案有两个明显的问题。 1st,记录在同一日期范围内(10 月 21 日和 10 月 23 日)内重复 2 个以上的日期。第二,这两个日期都以 2 个不同的位值重复,因此不能简单地使用 DISTINCT。我觉得可能成为问题的第三个问题是性能。也许有一种更有效的方法来实现这一点(也许使用函数)而不是使用递归 CTE。
【问题讨论】:
-
对于您的
1st和2nd问题,一个快速的方法是执行GROUP BY DateVal、MAX(isMyDate)。为了提高性能,请使用计数表而不是递归 cte -
一周内最多可以有 7 行,对吗?你说这个表很大,你是否需要对整个表每次运行查询,或者你是否会有比所有时间更小的日期范围的合理谓词>?
标签: sql sql-server date tsql sql-server-2016