如何使用SQL语句计算每月的第三个星期一?

时间:2012-01-12 11:39:01

标签: mysql

我需要触发通知。这个通知必须每个月的第三个星期一触发。

9 个答案:

答案 0 :(得分:2)

SELECT 
(
  DAYOFWEEK(NOW()) = 2  
  AND 
  DAYOFMONTH(NOW()) BETWEEN 15 AND 21
) 
AS send_notice_today;

答案 1 :(得分:1)

尝试使用 dayofweek dayofmonth 功能。 http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_dayofweek

不知何故,您可以使用 dayofmonth (使用操作模式7)检查从1月1日到curdate()的周数,并且 dayofweek 应为5(周四)

答案 2 :(得分:0)

当前月份的第三个星期一的日期将由SQL语句给出:

SELECT date_add(date_sub(curdate(),INTERVAL dayofmonth(curdate())-1 DAY), 
    INTERVAL (7-weekday(date_sub(curdate(),INTERVAL dayofmonth(curdate())-1 DAY)))+14 DAY)

答案 3 :(得分:0)

我采取的方法是获取本月的第一个星期一,并根据月份的时间,添加2或3周(因为它在周一之前/之后失效,你只需要走2个星期):

 ;with  
 filler as (select row_number() over (order by a) a from (select top 100 1 as a from syscolumns) a cross join (select top 100 1 as b from syscolumns) b),
 dates as (select dateadd(month, a-1, '1/1/1900') date from filler where a <= 2000),
 FirstMonday as (
 select dateadd(day, case   datepart(weekday,Date)
                            when 1 then 1
                            when 2 then 0
                            when 3 then 6
                            when 4 then 5
                            when 5 then 4
                            when 6 then 3
                            when 7 then 2
                        end, Date) as Date
        ,case when datepart(weekday,Date) = 1 then 3 else 2 end as Weeks
 from   dates
 )
 select dateadd(week, Weeks, Date) as ThirdMonday
 from FirstMonday

答案 4 :(得分:0)

这个计算给定年月日的任何月份的第一个星期一

SET @firstday = '2015-04-01';
SELECT ADDDATE( @firstday , MOD((9-DAYOFWEEK(@firstday)),7)) as first_monday;

这个计算给出年 - 月 - 日的任何月份的第三个星期一

SET @firstday = '2015-01-01';
SELECT ADDDATE( @firstday , MOD((23-DAYOFWEEK(@firstday)),21)) as third_monday;

这个计算了给出年 - 月 - 日的任何月份的第三个星期五

SET @firstday = '2015-09-01';
SELECT ADDDATE( @firstday , MOD((20-DAYOFWEEK(@firstday)),20)) as third_friday;

感谢@Brewal提出原始问题,感谢@ User2208436指出我们的答案。

答案 5 :(得分:0)

以下是不使用DAYOFWEEKDAYOFMONTH的答案。它仅使用DATEADDDATEPART

我们需要两个辅助函数:

CREATE FUNCTION dbo.day_of_week(@date Date)
RETURNS INT
AS BEGIN
    -- (1 for Sunday, 2 for Monday, etc)
    RETURN DATEPART(dw, DATEADD(year, year(@date)-1900, DATEADD(month, month(@date)-1, DATEADD(day, day(@date)-1, 0))))
END
GO

CREATE FUNCTION dbo.date_from_parts(@year INT, @month INT, @day INT)
RETURNS DATE
AS BEGIN
    RETURN DATEADD(year, @year-1900, DATEADD(month, @month-1, DATEADD(day, @day-1, 0)))
END
GO

然后使用以下示例数据:

DECLARE @day_of_week INT
SET @day_of_week = 2 -- Monday

DECLARE @year INT
DECLARE @month INT
SET @year = 2016
SET @month = 11

让我们首先获得本月的第一个星期一:

我们会在每月的第一天添加偏移量(day_of_week - day of week of first day of the month) % 7

(另请注意,我们需要构建((x % n) + n) % n而非x % 7,以便在06内保持答案。例如,只需SELECT -3 % 7返回-3!请参阅Mod negative numbers in SQL just like excel

现在这是获得本月第一个星期一的最终建设:

SELECT
    DATEADD(
        dd,
        (((@day_of_week -
           dbo.day_of_week(dbo.date_from_parts(@year, @month, 1))) % 7) + 7) % 7,
        dbo.date_from_parts(@year, @month, 1)
    )

要获得该月的第三个星期一,请在此答案的第二个字词中添加14。

答案 6 :(得分:0)

如果@firstday是该月的第一天

select date_add(@firstday,
         interval (if(weekday(@firstday)>0,21-weekday(@firstday),14)) day);

收获该月的第3个星期一。

经过2018年所有月份的测试。

似乎比以前的解决方案更简单。

关键是工作日的if函数。

如果工作日= 0(第一天是星期一),请添加14天 如果工作日&gt; 0,添加21天并减去工作日

答案 7 :(得分:0)

或许更常见的是,你可以使用这个来获得日期的“一周”:

(FLOOR((DAYOFMONTH(给定) - 1)/ 7))AS'week_of_month'

我相信在给定日期提供准确的0周的周指数。然后你可以使用该值来查找任何nth,如:

WHERE(week_of_month)= n和工作日= {工作日}

你也可以使用上面的内容来获得“last {weekday}”:

WHERE(week_of_month&gt; = 4)和weekday = {weekday}

请注意,week_of_month的范围可以是0到5(例如,31日的月份,其中第1个星期六将是第6周的第31个星期(5个作为基于0的索引)

希望这会有所帮助...

再确定一下......你可以将上面定义为函数,如下所示:

CREATE FUNCTION WEEKOFMONTH(given date) RETURNS int DETERMINISTIC RETURN (FLOOR((DAYOFMONTH(given) - 1) / 7))

并添加另一个功能:

CREATE FUNCTION WEEKNAME(given date) RETURNS text CHARACTER SET utf8 COLLATE utf8_unicode_ci DETERMINISTIC RETURN (CONCAT(ELT(WEEKOFMONTH(given)+1,'1st ','2nd ','3rd ','4th/Last ','5th/Last '),DAYNAME(given)))

然后你可以简单地说出像

这样的东西
SELECT * FROM dataTable WHERE WEEKNAME(your_date_field) = "3rd Wednesday"

......我在第四次/第五次应该如何从WEEKDAY返回,并决定在这个“足够好”的理论下添加“/ Last”,如果想要测试4号,5号或者持续。使用此功能,您可以:

SELECT * FROM dataTable WHERE WEEKNAME(your_date_field) LIKE "%Last%"

答案 8 :(得分:0)

DECLARE @YEAR DATE='2019-01-01'
SELECT DATEADD( d, 23-(DATEPART(dw,@YEAR )%21),@YEAR )

这将有助于获取所需月份的第三个星期一。