关于sql:如何在不使用CTE的情况下从日期范围创建日期列表

How to create a list of dates from a daterange without using a CTE

以下链接说明了如何将日期范围转换为日期列表。
我使用了这种方法,并且效果很好,但是查询没有执行(我使用Maxrecursion 0进行了无限制)。

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

还有其他解决方案可以做到这一点吗? (使用子查询还是声明表?)


尝试

1
2
3
4
5
6
7
8
9
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年。.

1
2
3
4
5
6
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


这是链接中的相同查询,但进行了较小的修改(使用CTE)。请检查:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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);