1

以下链接说明了如何将日期范围转换为日期列表。我使用了这种方法,它工作正常,但查询没有执行(我使用 Maxrecursion 0 来无限)。

http://blog.justinstolle.com/sql-turn-a-date-range-into-a-list-of-dates/

有没有其他解决方案来完成这项工作?(使用子查询或声明表?)

4

2 回答 2

3

尝试

declare @datestart date = '2012-1-1',   @dateend date = '2012-10-31'

declare @days int = datediff(d,@datestart,@dateend)

select
    dateadd(d, number, @datestart)
from master..spt_values 
where type='p'
    and number<=@days

如果您的日期范围超过 2047 天,您可以通过自行加入表格来延长它 - 下面将允许您长达 27 年。

select
    dateadd(d, v1.number+v2.number*2048, @datestart)
from master..spt_values v1
    cross join (select number from master..spt_values where number<5 and type='p') v2       
where type='p'
    and (v1.number+v2.number*2048)<=@days
于 2012-10-31T11:11:02.240 回答
-1

这是链接中的相同查询,稍作修改(使用 CTE)。请检查:

DECLARE @dateranges TABLE (range_id VARCHAR(2), date_begin DATETIME, date_end DATETIME)
INSERT @dateranges SELECT 'A', '2010-01-01', '2010-01-03'
INSERT @dateranges SELECT 'B', '2008-02-27', '2008-03-01'
INSERT @dateranges SELECT 'C', '2010-04-26', '2010-04-26'
INSERT @dateranges SELECT 'D', '2000-02-01', '2001-02-05'

;WITH cte (id, d)
AS (SELECT tbl.range_id AS id, tbl.date_begin AS d
    FROM @dateranges tbl
    WHERE DATEDIFF(DAY, tbl.date_begin, tbl.date_end) >0
    UNION ALL
    SELECT tbl.range_id AS id, DATEADD(DAY, 1, cte.d) AS d
    FROM cte INNER JOIN @dateranges tbl
    ON cte.id = tbl.range_id
    WHERE cte.d < tbl.date_end)
SELECT id AS range_id, d AS date_within_range FROM cte
ORDER BY id, d
OPTION (MAXRECURSION 0);
于 2012-10-31T11:42:55.183 回答