繁体   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