mysql 每月第N个工作日

ggazkfy8  于 12个月前  发布在  Mysql
关注(0)|答案(5)|浏览(149)

我想做的伪代码:

SELECT * FROM table WHERE NTH_DAY(DATE(table_date)) = NTH_DAY($input_date);

字符串
我想确定给定日期的第n个工作日是什么。例如,如果输入“2013-08-30”,它应该返回5,因为它是该工作日(星期五)在该月的第五次出现。
我已经阅读了无数类似的问题,但大多数人都在寻找相反的,例如,他们想找到第五个星期五的日期,而我想确定日期的第n个数字是什么。
有人能解释一下这在MySQL查询中是否可能以及如何做到这一点吗?

blpfk2vs

blpfk2vs1#

要找出一个给定的“第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

e5nqia27

e5nqia272#

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

SELECT WEEK(dateasd,5) - 
WEEK(DATE_SUB(dateasd, INTERVAL DAYOFMONTH(dateasd)-1 DAY),5)
from test

字符串
使用Weekday()函数查找当前日期
Fiddle,网址:http://www.sqlfiddle.com/#!2/7a 8b 6/2/0

l2osamch

l2osamch3#

我会把我的两分钱和第三个选项放在一起,这个选项是基于每天的第一天,然后加上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 = Sun),monthOfYear为1到12。

    • 示例**

查看日期是否为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


此检查确保日期具有正确的星期几和正确的月份(以防用户传入的日期甚至不是正确的星期几)。

DAYOFWEEK(checkDate) = dayOfWeek AND MONTH(checkDate) = monthOfYear


现在是最重要的一个:

DAYOFMONTH(checkDate) = ((1 + (7 + dayOfWeek - DAYOFWEEK(firstOfMonth)) % 7) + 7 * (weekNumber - 1))


为了得到我们需要加到1上以得到日期的量,我们计算我们正在查看的dayOfWeek,减去该月福尔斯的第一天所在的星期几,以得到偏移量mod 7((dayOfWeek-DayOfWeek(first))% 7)。
注意,因为一个月的第一天可能会在我们看到的前一天或当天,我们添加了一个额外的7,然后以7为模。这是必要的,因为MySQL的Mod函数不能正确计算mod。即-1% 7应该是6,但MySQL返回-1。添加7并取模确保结果总是正确的。
总结如下:

NumberToAddToOneToGetDateOfFirstWeekDay = (7 + DayOfWeek - DayOfWeek(firstDayOfMonth)) %


然后我们加上1,以及需要多少个7的倍数才能得到正确的一周。

ef1yzkbh

ef1yzkbh4#

select ceiling(DATEPART(day, GETDATE())/7.0)

字符串
这将始终给予您当前日期在一个月中的第n次出现次数。例如,如果当前日期是星期五,并且它在这个月中出现了第3次。它将返回3。如果您将GETDATE()替换为Date变量或列名,它将返回该日期在相应月份中的出现次数。

c2e8gylq

c2e8gylq5#

老实说,如果你需要做这种查询,我会简单地构建一个包含所有日期的表,你可以从中进行查找。
使用MySQL 8.0,你可以:

WITH RECURSIVE dates AS (
   SELECT CAST('2023-01-01' as DATE) as D
   UNION ALL
   SELECT DATE_ADD(D, INTERVAL 1 DAY) FROM dates WHERE d<='2023-12-31'
)
SELECT 
    d,
    day(d) as day,
    DATE_FORMAT(d,'%w') as weekday,
    rank() over (partition by DATE_FORMAT(d,'%m'),DATE_FORMAT(d,'%w') order by d) as nth_weekday
FROM dates 
WHERE DATE_FORMAT(d,'%Y')=2023
ORDER BY d
;

字符串
参见:DBFIDDLE
或者,对于MSSQL变体:DBFIDDLE MSSQL

相关问题