2012-01-25 8 views
0

SQLレポートsprocのWHERE句を更新して、指定された日付がクラスの次のオカレンスに来るかどうかを調べようとしています。クラスはStartDateを持ち、毎週同じ日に週に1回発生します。 StartDateを指定すると、その曜日の次の発生をどのように見つけることができますか?SQLの曜日の次の出現箇所を見つける

E.G. StartDateが2012年1月18日、水曜日で、2012年1月26日の今日のレポートを実行すると、1/26の次の水曜日である2012年2月1日が必要です。 StartDateが1/19、木曜日で、今日レポートを実行すると、式は1/26木曜日になります。ここで

は、SQLでのアイデアのようなものです:

SELECT * 
FROM tbl_Class cs 
INNER JOIN tbl_Enrollment sce ON cs.pk_ClassID = sce.fk_ClassID 
WHERE ... 
AND sce.StartDate < [Find date of next class after @AsOfDate using cs.StartDate] 

答えて

1

ここに私が思い付いたいくつかの例のSQLです。 3回繰り返すので、どのように私が最後までやって来るかを追うことができます。 3回目の反復は、変数にカラム名を代入することでWHERE句に組み込むことができます。

セットアップ:

DECLARE @Startdate DATETIME,@currentdate datetime 
SET @Startdate = '1-26-2012' 
SET @Currentdate = '1-23-2012' 

--This section just normalizes it so you can use 7 as the interval 
--The offset depends on your current setting for DATEFIRST, U.S. English default is 7, Sunday. 
-- see http://msdn.microsoft.com/en-us/library/ms187766.aspx 
DECLARE @StartDateWorkingDayOfWeek int,@CurrentDateWorkingDayOfWeek int 
SELECT @StartDateWorkingDayOfWeek =(DATEPART(weekday,@Startdate)-2) 
SELECT @CurrentDateWorkingDayOfWeek=(DATEPART(weekday,@Currentdate)-2) 

反復#1

--Iteration 1 
IF @StartDateWorkingDayOfWeek < @CurrentDateWorkingDayOfWeek 
SELECT DATEADD(DAY,DATEDIFF(DAY,0,@Currentdate)/7*7 + 7,@StartDateWorkingDayOfWeek) 
else 
SELECT DATEADD(DAY,DATEDIFF(DAY,0,@Currentdate)/7*7 + 0,@StartDateWorkingDayOfWeek) 

反復#2

--Iteration 2 
SELECT DATEADD(DAY,DATEDIFF(DAY,0,@Currentdate)/7*7 + 

CASE WHEN @StartDateWorkingDayOfWeek < @CurrentDateWorkingDayOfWeek 
    then 7 
    ELSE 0 
    end 

    ,@StartDateWorkingDayOfWeek) 

反復#3

--iteration 3 
SELECT DATEADD(DAY,DATEDIFF(DAY,0,@Currentdate)/7*7 + 

CASE WHEN (DATEPART(weekday,@Startdate)-2) < (DATEPART(weekday,@Currentdate)-2) 
    then 7 
    ELSE 0 
    end 

    ,(DATEPART(weekday,@Startdate)-2)) 
この記事への3210

帽子のヒント:http://www.sqlmag.com/article/tsql3/datetime-calculations-part-3

私たちは、現在の日付の前の月曜日の排他的の日付を取得することができます(:ここ http://www.sqlmag.com/article/tsql3/datetime-calculations-part-3

+0

'DATEPART(WEEKDAY'は(http://stackoverflow.com/a/5984859/73226) –

+0

マイ米国/英語中心ネスストライキ再び!おかげで、マーティン[@@ DATEFIRST''に依存しています] – TetonSig

+0

私は同じことを指摘するつもりでしたが、2の減算は@@ datefirstが7に設定されていることを前提としています。 @@ datefirstへの依存をなくし、条件文を必要としない別の解決策を見つけたと思います。ご利用いただきありがとうございます。 – xr280xr

0

は私がTetonSigに感謝し、このリンクに彼の参照思い付いたものです@AsOfDate)そうのように:

SELECT DATEADD(day, DATEDIFF(day,0, @AsOfDate-1) /7*7, 0); 

これは、日中に1900年1月1日と@AsOfDate間の日数を取得します。/7 * 7はそれを週全体に変換し、1900年1月1日(月)に戻して@AsOfDateの前の月曜日を取得します。 -1は@AsOfDateを排除します。マイナス1がなければ、@ AsOfDateが月曜日にあった場合、それは「前の」月曜日とみなされます。

次の著者は包括次月曜日取得することを示し、我々は単に排他以前の月曜日の式に7を追加する必要があります。

SELECT DATEADD(d, DATEDIFF(day,0, @AsOfDate-1) /7*7, 0)+7; 

出来上がり!私たちは@AsOfDate以降の最初の月曜日を取得しました。唯一の問題は、上記の月曜日(0)が私の場合の動くターゲットだということです。最初の月曜日ではなく、クラスの日付で決められた最初の[DayOfWeek]が必要です。私は上記の0のためClassDayOfWeek計算をスワップアウトする必要があります。

DATEADD(d, DATEDIFF(d, [ClassDayOfWeek], @AsOfDate-1)/7*7, [ClassDayOfWeek])+7 

私はに依存しているかDATEFIRST @@設定で混乱することなく、ClassDayOfWeekを計算したかったです。だから私は、基準日からの相対それを計算:

DATEDIFF(d, 0, StartDate)%7 

これは、私たちが今[ClassDayOfWeek]のためにそれをプラグインすることができます日のために月、6 0を与えます。この0〜6の値は、1/1/1900-1/7/1900がintとして表される日付であることを指摘しておきます。

DATEADD(d, DATEDIFF(d, DATEDIFF(d, 0, StartDate)%7, @AsOfDate-1)/7*7, DATEDIFF(d, 0, StartDate)%7)+7 

、問題ごとの使用中:

SELECT * 
FROM tbl_Class cs 
INNER JOIN tbl_Enrollment sce ON cs.pk_ClassID = sce.fk_ClassID 
WHERE ... 
AND sce.StartDate < DATEADD(d, 
          DATEDIFF(d, 
            DATEDIFF(d, 0, cs.StartDate)%7, 
            @AsOfDate-1)/7*7, 
          DATEDIFF(d, 0, cs.StartDate)%7)+7 
0

私はシンプルcase文と解答を導出しました。
状況によっては、@ targetDOWはクラスの曜日になります。

DECLARE @todayDOW INT = DATEPART(dw, GETDATE()); 
DECLARE @diff INT = (@targetDOW - @todayDOW); 

SELECT 
    CASE 
     WHEN @diff = 0 THEN GETDATE() 
     WHEN @diff > 0 THEN DATEADD(d,@diff,GETDATE()) 
     WHEN @diff < 0 THEN DATEADD(d,@diff + 7,GETDATE()) 
    END; 
関連する問題