次のリンクでは、日付範囲を日付のリストに変換する方法について説明しています。私はこのアプローチを使用しましたが、正常に動作しますが、クエリは実行されません (Maxrecursion 0 を使用して制限を解除しました)。
http://blog.justinstolle.com/sql-turn-a-date-range-into-a-list-of-dates/
これを行うための他の解決策はありますか?(サブクエリまたは宣言テーブルを使用していますか?)
次のリンクでは、日付範囲を日付のリストに変換する方法について説明しています。私はこのアプローチを使用しましたが、正常に動作しますが、クエリは実行されません (Maxrecursion 0 を使用して制限を解除しました)。
http://blog.justinstolle.com/sql-turn-a-date-range-into-a-list-of-dates/
これを行うための他の解決策はありますか?(サブクエリまたは宣言テーブルを使用していますか?)
試す
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
これはリンク内の同じクエリで、(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);