2

私は SQL を初めて使用します。誰でもこのシナリオについてクエリを実行できますか?「今日の日付から次の 8 週間までの週の開始日と終了日を表示する必要があります」. たとえば、今日の日付を選択すると、表示されるはずです

  1. 開始日 | 終了日
  2. 2012/03/17 | 2012/03/23
  3. 2012/03/24 | 2012/03/29
  4. ..など
  5. 2012 年 4 月 28 日 | 2013 年 3 月 5 日
4

3 に答える 3

1

これを試して:

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
于 2013-03-21T11:24:06.490 に答える
0

この 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

お役に立てれば!

于 2013-03-21T10:36:13.870 に答える
0

反復を避けたい場合 (たとえば、ビューでこのデータが必要な場合) は、次の手法を使用できます。

;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

これを拡張して、予測する週数のパラメーターを取得するのは簡単な変更です。

于 2013-03-21T11:20:01.337 に答える