2017-02-21 8 views
-1

「1月の最後の日曜日」の日付を選択するT-SQLコードを探しています。例えばSQL Serverの自動ピックアップ日付

select 
    convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), GETDATE(), 112) + '0101')), 30))/7 * 7, '19000107'), 120) 
:今年は、私は、SQL Server 2014で使用されているいくつかのT-SQLコードを持っている1月

の最終日曜日から始まるので

Current day  expected result 
2017-01-29  2016-01-31 
2017-02-05  2017-01-29 
2017-02-19  2017-01-29 
2018-01-28  2017-01-29 
2018-02-04  2018-01-28 

これは、

現在の日付が2月から12月の場合、上記のコードは正しい答えを返します。しかし、現在の日付を '2017-01-25'(または1月の他の日付)に設定すると、結果は間違っています。

上記の日付については

(2017年1月25日)答えなければならないことが「2016年1月31日」

+0

DATEPARTまたはDATENAME関数のどちらかが、これでお手伝いをします:サンプルの結果を更新しました

。 –

+0

@ dan-bracuk T-SQLコードを更新して送信できますか?非常に役に立ちます。 – user2331670

答えて

2

1月の最初の日が検索されている可能性がありますが、1月が指定された月である場合は、これは異なることになります。 Janが指定された月であるかどうかを調べ、昨年を年として返します。変更が行われた場所

select 
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30))/7 * 7, '19000107'), 120) 

CONVERT(date, CONVERT(VARCHAR(4)CASE文は...です。

+0

ありがとうございました。別のシナリオのために別のT-SQLコードが必要です。シナリオは「同じ概念の場合、T-SQLコードで前年の日付を選択します。たとえば、1.現在の日付は '2017-02-21'で、コードは '2016-01-31'を選択する必要があります。現在の日付は '2018-02-21'で、コードは '2017-01-29'を選択する必要があります。助けてください。 – user2331670

0

ルックアップテーブルこの種の問題を解決するための最良の方法です

WITH lookup(d) AS 
(
    VALUES(('2016-01-31'), 
      ('2017-01-29'), 
      ('2018-01-28') 
) 
select MAX(d) 
FROM lookup 
WHERE d <= GETDATE() 
0

この右端の列は、1月の直前の最後の日曜日を任意の日付として計算します。私は論理を文書化して実験する簡単な方法として他の列を残しました。

分岐ロジックはありません。純粋な日付演算であるため、合理的に高速に集計する必要があり、日付列にインデックスを使用できるはずです。

DECLARE @Date DATE = '20170205'; 
SELECT SampleDate= @Date , 
    PreviousLastSundayInJanuaryForSampleDate = DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH 
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))-1)*-1 
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH 
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date))-1)*-1 
,DATEADD(DAY,((DATEPART(DAYOFYEAR,DATEADD(DAY,(DATEPART(WEEKDAY,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))-1)*-1,EOMONTH(DATEADD(MONTH,(DATEPART(MONTH,@Date)-1)*-1,@Date)))))-1) * -1 ,@Date)))) 

これをテーブルに対して使用するには、@ Dateを自分の日付フィールドに置き換えます。

SampleDate PreviousLastSundayInJanuaryForSampleDate 
2008-06-03 2008-01-27 
2008-12-20 2008-01-27 
2009-07-08 2009-01-25 
2010-01-24 2009-01-25 
2010-08-12 2010-01-31 
2011-02-28 2011-01-30 
2011-09-16 2011-01-30 
2012-04-03 2012-01-29 
2012-10-20 2012-01-29 
2013-05-08 2013-01-27 
2013-11-24 2013-01-27 
2014-06-12 2014-01-26 
2014-12-29 2014-01-26 
2015-07-17 2015-01-25 
2016-02-02 2016-01-31 
2016-08-20 2016-01-31 
2017-03-08 2017-01-29 
2017-09-24 2017-01-29 
2018-04-12 2018-01-28 
2018-10-29 2018-01-28 
2019-05-17 2019-01-27 
2019-12-03 2019-01-27 
2020-06-20 2020-01-26 
関連する問題