簡體   English   中英

T-SQL日期提取

[英]T-SQL date pickup

我正在尋找一些T-SQL代碼,該代碼應選擇“距當前日期一年的時間(在一月份的最后一個星期日的同一時間)”。

我有一些在SQL Server 2014中使用的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)

上面的代碼選擇當年的日期(一月的最后一個星期日)。 但是我希望T-SQL代碼選擇去年的日期(一月月份的最后一個星期日的日期)。

詳細信息-我希望T-SQL代碼從下表中產生預期的結果

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

請注意,年份總是從“一月的最后一個星期日”開始。

將會有更簡潔的解決方案,但是當我們假設您的代碼經過時間測試並且健壯時,我將用現在為負一年的表達式替換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)

如果您有日歷表,則可以跳過第一個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 @today這些行過濾為1月份的@today之前的日期,該日期是星期日(使用已知有效日期,而不是依賴於任何特定的DATEFIRST設置),並且介於該月的25日至31日之間。

然后,如果我們的年份從每年一月的最后一個星期日開始,那么我們選擇這些日期中的第二個日期,該日期必須是去年的開始。


如果你對一個完整的,而您希望找到這個“去年開始”日期表工作價值,你會介紹它的joinApplicableDates CTE和分區ROW_NUMBER()聚合使用這些值,從而使您可以並行查找所有星期日。

這將使列與數據隔離。

請嘗試一下,讓我知道。 謝謝。

    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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM