2013-08-21 49 views
2

伪码的第N个工作日:的想什么,我做了一个月

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

我想,以确定哪些月份的第n个工作日是给定日期。例如,如果输入“2013-08-30”,则应该返回5,因为这是该月中该周五(星期五)的第五次发生。

我一直在阅读无数类似的问题,但大多数人都在寻找恰恰相反的人,例如他们想找到第五个星期五的日期,而我想确定日期的第n个数字是什么。 Other questions似乎是我所追求的,但他们使用不同的编程语言,我不明白。

有人可以请解释,如果这是可能的MySQL查询和如何做到这一点?

+0

@Dancrumb无论今天是哪一天。 –

+0

老实说,如果你需要做这样的查询,我会简单地建立一个可以做查找的日期的表格。类似于在数据仓库中创建日期维度表的方式。像这样的https://gist.github.com/johngrimes/408559请阅读这里了解更多关于维度表的内容(请参阅常见模式部分)http://en.wikipedia.org/wiki/Dimension_%28data_warehouse%29 –

回答

4

找哪家“第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 
0

这将使本周的数量(这实际上是一样的,如果它是第5日或5日星期一)

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

使用平日()函数来找到它是一天

小提琴在 http://www.sqlfiddle.com/#!2/7a8b6/2/0

+0

我是不知道我在这里遵循你的逻辑。您提供的示例将日期2013-08-21输入到数据库中,并且您的查询返回4.该日期是第三个星期三,因此我正在查找它以返回3. –

+0

+1是一个问题,基本功能基本上返回一年的那一周,然后我找到该月的第一天的一周并扣除它,这就是逻辑 – skv

1

我要去把我的两分钱在这里与得到它基于发现每一天的1日第三个选项,然后添加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,星期为1至7(1 =星期日),和monthOfYear是1至12。

示例

要检查是否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 

此检查可确保日期有星期的正确日子,正确的月份(以防万一用户在通过日期甚至不是一周的正确日期)。

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

现在的大单:

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

要得到我们需要添加到1来获得日期的金额,计算一周中的某天,我们正在寻找,减去星期几那个月的第一天就会得到偏移量mod 7((dayOfWeek - DayOfWeek(first))%7)。

请注意,由于本月的第一个月可能会在我们正在查看的前一天或某一天出现,因此我们会再增加一个7,然后再增加7。这是需要的,因为MySQL的Mod功能不能正确计算mod。即-1%7应该是6,但是MySQL返回-1。加7和取模可确保结果总是正确的。

总结:

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

然后,我们添加一个需要的7每一好几倍怎么去正确的一周。