2013-08-21 50 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每一好幾倍怎麼去正確的一週。