![](/img/trans.png)
[英]MySQL: Get date based on the nth day of the week on a particular month/year
[英]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.