2017-02-22 7 views
0

私は現在の日付から1年前(1月の最後の日曜日)である日付を選択するT-SQLコードを探しています。T-SQLの日付ピックアップ

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) 

上記のコードは、(1月の月の最終日曜日)、現在の年のための日付をピックアップ:

は、私は、SQL Server 2014で使用されているいくつかのT-SQLコードを持っています。しかし、T-SQLコードで昨年(1月の最後の日曜日の日付)の日付を選択する必要があります。具体的には

- 私は

テーブルの下から
Current day    Expected result 
--------------------------------------- 
2017-02-05    2016-01-31 
2017-01-05    2015-01-25 
2018-02-19    2017-01-29 
2018-01-19    2016-01-31 
2019-02-28    2018-01-28 

期待される結果を生成するために、T-SQLコードを望ん年は「1月の月の最終日曜日」から始まり、常に注意してください。

答えて

3

あり、より簡潔なソリューションとなりますが、私たちはあなたのコードは、時の試練と堅牢であることを前提としていたとき、私は単に1年減じたものになりました式でGETDATE()を代用になります。したがって

DATEADD(year, -1, GETDATE()) 

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

非常にうまくいった感謝 – user2331670

0

これは、データを含む列を非表示にします。

私に教えてください。ありがとう。

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) AS CurrentDay , convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), 
DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30))/7 * 7, '19000107'), 120) as ExpectedResult 
+0

ありがとう、しかし@@@ dlatikayの答えは – user2331670

+0

問題ない@ user2331670 – FreedomPride

3

カレンダーテーブルを持っている場合は、あなたが最初のCTE(そしておそらくMAXRECURSIONオプション)をスキップしてちょうどカレンダーのテーブルを使用することができます。うまくいけば、これは明らかに正しいです:

declare @today date 
set @today = CURRENT_TIMESTAMP 

;With Dates as (
    select CONVERT(date,'19000101') as d 
    union all 
    select DATEADD(day,1,d) from Dates where d < '21000101' 
), ApplicableSundays as (
    select d,ROW_NUMBER() OVER (ORDER BY d desc) as rn 
    from Dates 
    where d < @today and 
    DATEPART(month,d) = 1 and 
    DATEPART(weekday,d) = DATEPART(weekday,'20150913') and --Any known Sunday 
    DATEPART(day,d) between 25 and 31 
) 
select d 
from ApplicableSundays where rn = 2 
option (maxrecursion 0) 

Datesは、あなたの目的のために十分にうまくいけば、柔軟で20日と21世紀、内のすべての日付を生成します。

ApplicableSundays

は、(特定のDATEFIRSTの設定に頼るのではなく、正常な日付を使用して)日曜日は、月にある@today前に発生した日付まで、これらの行をフィルタリングし、25日と、その月の31日の間に入ります。

これらの日付のうち、最近2番目の日付を選択します。これは、1月の最後の日曜日から年が始まる場合、昨年の開始日である必要があります。あなたは、この「スタート昨年の」値を見つけるしたいの日付の完全なテーブルに対して作業している場合


、あなたはApplicableDates CTEでjoinとしてそれを導入し、使用してROW_NUMBER()集計を分割しますこれらの値は、すべての日曜日を並行して見つけることができます。

+0

大きい、正しいおよび多才。しかし:私の答えの実行計画= 1つのノード、 "クエリなしで選択"。この実行計画=深さ13の木:) – dlatikay

+0

@dlatikay - うん。私はあなたのことを見てきましたが、私は実際の論理が何であるかまだ分かりません。私の複雑さの中には、カレンダーテーブルを使いたいと思っている人がいますが、スタンドアロンスクリプトを提供したい人もいます。 –

関連する問題