私は SQL を初めて使用します。誰でもこのシナリオについてクエリを実行できますか?「今日の日付から次の 8 週間までの週の開始日と終了日を表示する必要があります」. たとえば、今日の日付を選択すると、表示されるはずです
- 開始日 | 終了日
- 2012/03/17 | 2012/03/23
- 2012/03/24 | 2012/03/29
- ..など
- 2012 年 4 月 28 日 | 2013 年 3 月 5 日
私は SQL を初めて使用します。誰でもこのシナリオについてクエリを実行できますか?「今日の日付から次の 8 週間までの週の開始日と終了日を表示する必要があります」. たとえば、今日の日付を選択すると、表示されるはずです
これを試して:
DECLARE @startDate DATETIME
DECLARE @currentDate DATETIME
DECLARE @numberOfWeeks INT
DECLARE @dates TABLE(
StartDate DateTime,
EndDate DateTime
)
SET @startDate = GETDATE()--'2012-01-01' -- Put whatever you want here
SET @numberOfWeeks = 8 -- Choose number of weeks here
SET @currentDate = @startDate
while @currentDate < dateadd(week, @numberOfWeeks, @startDate)
begin
INSERT INTO @Dates(StartDate, EndDate) VALUES (@currentDate, dateadd(day, 6, @currentDate))
set @currentDate = dateadd(day, 7, @currentDate);
end
SELECT * FROM @dates
これにより、次のようなものが得られます。
StartDate EndDate
21/03/2013 11:22:46 27/03/2013 11:22:46
28/03/2013 11:22:46 03/04/2013 11:22:46
04/04/2013 11:22:46 10/04/2013 11:22:46
11/04/2013 11:22:46 17/04/2013 11:22:46
18/04/2013 11:22:46 24/04/2013 11:22:46
25/04/2013 11:22:46 01/05/2013 11:22:46
02/05/2013 11:22:46 08/05/2013 11:22:46
09/05/2013 11:22:46 15/05/2013 11:22:46
または、時間コンポーネントが必要ない場合は、次のように最終的な選択を微調整できます。
SELECT CONVERT(VARCHAR, StartDate, 103), CONVERT(VARCHAR, EndDate, 103) FROM @dates
この StackOverFlow の投稿を見ることができます: TSQL で増分日付の結果セットを生成する
また
以下はその結果を与えるはずです:
declare @dateIterator datetime = getdate();
declare @endDate datetime = dateadd(week, 8, getdate());
declare @dateRange varchar(max) = '';
while @dateIterator < @endDate
begin
set @dateIterator = dateadd(day, 1, @dateIterator);
set @dateRange = @dateRange + ' ' + convert(varchar(10), @dateIterator, 3)
end
select @dateRange
お役に立てれば!
反復を避けたい場合 (たとえば、ビューでこのデータが必要な場合) は、次の手法を使用できます。
;WITH w(weeknumber) AS
(SELECT 0
UNION SELECT 1
UNION SELECT 2
UNION SELECT 3
UNION SELECT 4
UNION SELECT 5
UNION SELECT 6
UNION SELECT 7),
f(firstdayofweek) AS
(SELECT DATEADD(ww,DATEDIFF(ww,0,GETDATE()),0)),
o(offsetweekdate) AS
(SELECT DATEADD(ww,w.weeknumber,f.firstdayofweek) FROM w,f)
SELECT
DATEADD(d,0,o.offsetweekdate) AS firstdayofweek,
DATEADD(d,6,o.offsetweekdate) AS lastdayofweek
FROM o
ここでw
は、0 から 7 までの数字のリストを生成しf
、週の最初の日を見つけ、o
これら 2 つを組み合わせて、次の 8 週間の週の開始日と終了日を与えます。
これの欠点は、予測される週数を増やすために、w の定義に余分な行を追加する必要があることです。これは、ループを使用せずに TSQL を使用して値の範囲を生成する組み込みの方法がないためです。
Jeff Moden は、 StackOverflow の別の場所で非常に役立つ範囲関数を投稿しました。 私はこの種のシナリオで使用したいと思っています。
CREATE FUNCTION [dbo].[Range](@startvalue integer,@endvalue integer)
RETURNS TABLE
AS
RETURN(
WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
E02(N) AS (SELECT 1 FROM E00 a, E00 b),
E04(N) AS (SELECT 1 FROM E02 a, E02 b),
E08(N) AS (SELECT 1 FROM E04 a, E04 b),
E16(N) AS (SELECT 1 FROM E08 a, E08 b),
E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
SELECT TOP (@endvalue-@startvalue+1) (N+@startvalue-1) AS Number
FROM cteTally
WHERE N <= (@endvalue-@startvalue+1))
これにより、単純な を使用して範囲を生成できますSELECT Number FROM RANGE(0,10)
。この関数を定義したら、元のコードは次のように縮小できます。
;WITH w(weeknumber) AS
(SELECT Number FROM Range(0,7)),
f(firstdayofweek) AS
(SELECT DATEADD(ww,DATEDIFF(ww,0,GETDATE()),0)),
o(offsetweekdate) AS
(SELECT DATEADD(ww,w.weeknumber,f.firstdayofweek) FROM w,f)
SELECT
DATEADD(d,0,o.offsetweekdate) AS firstdayofweek,
DATEADD(d,6,o.offsetweekdate) AS lastdayofweek
FROM o
これを拡張して、予測する週数のパラメーターを取得するのは簡単な変更です。