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); |