簡體   English   中英

獲取每月第n周第n天的日期

[英]Get date for nth day of week in nth week of month

我有一列的值,例如“ 3rd-Wednesday”,“ 2nd-Tuesday”,“ Every-Thursday”。

我想創建一個讀取這些字符串的列,並確定該日期是否已到本月,如果已經到,則返回下個月的日期。 如果這個月還沒有過去,那么它將返回這個月的日期。

上述的預期結果(2016年4月22日)將為:'05 -18-2016','05-10-2016','04-28-2016'。

我更喜歡數學上的方法,並且盡可能避免創建日歷表。

謝謝。

部分答案,這絕不是錯誤。

這並不適合“每個”條目,但希望能給您一些啟發。 我確信有很多測試用例會失敗,並且最好寫一個存儲的proc。

我確實嘗試過通過計算月份的第一天的日期名稱和天數,然后計算下一個想要的日期並應用偏移量來做到這一點,但這很麻煩。 我知道您說沒有日期表,但CTE可以簡化事情。

這個怎么運作

CTE為日期和日期的當前月份創建日歷。 一些相當可疑的解析代碼從測試數據中提取了日期名稱,並加入了CTE。 where子句過濾的日期大於第N個出現的日期,如果日期已過,則select加4周。 或至少這是理論:)

我正在使用DATEFROMPARTS來簡化代碼,這是SQL 2012的功能-SO的替代品是2008。

SELECT * INTO #TEST FROM (VALUES ('3rd-Wednesday'), ('2nd-Tuesday'), ('4th-Monday')) A(Value)

SET DATEFIRST 1

;WITH DAYS AS (
    SELECT 
    CAST(DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE()),N.Number) AS DATE) Date, 
    DATENAME(WEEKDAY, DATEADD(MONTH,DATEDIFF(MONTH,0,GETDATE()),N.Number)) DayName 
    FROM master..spt_values N WHERE N.type = 'P' AND N.number BETWEEN 0 AND 31
)
SELECT 
    T.Value,
    CASE WHEN MIN(D.Date) < GETDATE() THEN DATEADD(WEEK, 4, MIN(D.DATE)) ELSE MIN(D.DATE) END Date
FROM #TEST T
JOIN DAYS D ON REVERSE(SUBSTRING(REVERSE(T.VALUE), 1, CHARINDEX('-', REVERSE(T.VALUE)) -1)) = D.DayName
WHERE D.Date >=
    DATEFROMPARTS(
        YEAR(GETDATE()), 
        MONTH(GETDATE()),
        1+ 7*(CAST(SUBSTRING(T.Value, 1,1) AS INT) -1)
        )
GROUP BY T.Value



Value         Date
------------- ----------
2nd-Tuesday   2016-05-10
3rd-Wednesday 2016-05-18
4th-Monday    2016-04-25

暫無
暫無

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

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