Mysql 每月第n个工作日

Mysql 每月第n个工作日,mysql,Mysql,我想做的伪代码: SELECT * FROM table WHERE NTH_DAY(DATE(table_date)) = NTH_DAY($input_date); 我想确定给定日期的每月第n个工作日。例如,如果输入“2013-08-30”,则应返回5,因为这是该月该工作日(星期五)的第五次出现 我已经阅读了无数类似的问题,但大多数人都在寻找相反的答案,例如,他们想找到第五个星期五的日期,而我想确定日期的第n个数字是多少。看起来像是我要找的,但他们用不同的编程语言,我不懂 有人能解释一下在

我想做的伪代码:

SELECT * FROM table WHERE NTH_DAY(DATE(table_date)) = NTH_DAY($input_date);
我想确定给定日期的每月第n个工作日。例如,如果输入“2013-08-30”,则应返回5,因为这是该月该工作日(星期五)的第五次出现

我已经阅读了无数类似的问题,但大多数人都在寻找相反的答案,例如,他们想找到第五个星期五的日期,而我想确定日期的第n个数字是多少。看起来像是我要找的,但他们用不同的编程语言,我不懂


有人能解释一下在MySQL查询中这是否可行以及如何实现吗?

这将给出一周的数字(实际上与第五个星期五或第五个星期一相同)

使用Weekday()函数查找当前日期

摆弄

要找到给定日期的第n个是相当容易的:

select (case when day(table_date) between 1 and 7 then 1
             when day(table_date) between 8 and 14 then 2
             when day(table_date) between 15 and 21 then 3
             when day(table_date) between 22 and 28 then 4
             else 5
        end) as NthDay
您也可以使用“余数”算法执行此操作:

select 1 + floor((day(table_date) - 1) / 7) ) as NthDay

我将在这里投入我的2美分,还有第三个选项,它基于找到每天的第一个,然后加上7的倍数得到最终结果

功能

CREATE FUNCTION `ISNTHDAYINMONTH`(checkDate DATE, weekNumber INTEGER, dayOfWeek INTEGER, monthOfYear INTEGER) RETURNS INTEGER
    NO SQL
    DETERMINISTIC
BEGIN
    DECLARE firstOfMonth DATE; 
    SET firstOfMonth = DATE_SUB(checkDate, INTERVAL DAYOFMONTH(checkDate) - 1 DAY); #Find the first day of the current month
    IF DAYOFWEEK(checkDate) = dayOfWeek AND MONTH(checkDate) = monthOfYear #Make sure at least this matches
        AND DAYOFMONTH(checkDate) = ((1 + (7 + dayOfWeek - DAYOFWEEK(firstOfMonth)) % 7) + 7 * (weekNumber - 1)) THEN #When the date matches the nth dayOfWeek day of the month
        RETURN 1;
    ELSE
        RETURN 0; #Nope
    END IF;
END
使用

SELECT ISNTHDAYINMONTH(datecol, weekNumber, dayOfWeek, monthOfYear);
其中weekNumber是1到5,dayOfWeek是1到7(1=太阳),monthOfYear是1到12

示例

SELECT ISNTHDAYINMONTH(datecol, weekNumber, dayOfWeek, monthOfYear);
要检查datecol是否为4月的第二个星期二,请执行以下操作:

SELECT ISNTHDAYINMONTH(datecol, 2, 3, 4);
计算

让我们把它分解一下。此行获取传入日期的月份第一天

SET firstOfMonth = DATE_SUB(checkDate, INTERVAL DAYOFMONTH(checkDate) - 1 DAY); #Find the first day of the current month
此检查确保日期具有正确的星期几和正确的月份(以防用户输入的日期甚至不是正确的星期几)

现在来看一个大问题:

DAYOFMONTH(checkDate) = ((1 + (7 + dayOfWeek - DAYOFWEEK(firstOfMonth)) % 7) + 7 * (weekNumber - 1))
为了得到需要加在1上才能得到日期的金额,我们计算我们正在查看的dayOfWeek,减去该月第一天所在的星期几,得到补偿mod 7((dayOfWeek-dayOfWeek(first))%7)

请注意,因为本月的第一天可能会在我们查看的前一天或当天着陆,所以我们添加了额外的7,然后mod by 7。这是必需的,因为MySQL的Mod函数不能正确计算Mod。也就是说,-1%7应该是6,但是MySQL返回-1。加上7并取模数可确保结果始终正确

总结如下:

NumberToAddToOneToGetDateOfFirstWeekDay = (7 + DayOfWeek - DayOfWeek(firstDayOfMonth)) % 
然后我们加上一个,以及需要多少乘以7才能得到正确的一周

select ceiling(DATEPART(day, GETDATE())/7.0)
这将始终为您提供一个月内当天的第n次出现次数。 例如,如果当前日期是星期五,并且发生在本月的第三次。它将返回3。
如果用日期变量或列名替换GETDATE(),它将返回相应月份中该日期发生的日期。

@Dancrumb不管是哪一天。老实说,如果您需要进行此类查询,我只需构建一个包含所有日期的表,您可以从中进行查找。类似于在数据仓库中创建日期维度表的方式。关于维度表的更多信息,请阅读这里的内容(参见公共模式部分),我不确定我是否遵循了您的逻辑。您提供的示例将日期2013-08-21输入数据库,查询返回4。该日期是第三个星期三,因此我希望它返回3。+1是一个问题,week函数基本上返回一年中的一周,然后我找到该月第一天的一周并将其扣除,这就是逻辑
select ceiling(DATEPART(day, GETDATE())/7.0)