2017-02-27 88 views
0

我一直試圖在2個給定日期之間得到週末天數(週六和週日)。返回週末天的MySQL函數

我碰到這樣的解決方案:http://crossedlogic.blogspot.ca/2008/09/using-sql-to-find-work-days-in-date.html

當我調用該函數,它返回作爲輸出消息OK,我想它返回的週末兩天的計數來代替。

我在做什麼錯?

代碼:

DROP FUNCTION IF EXISTS `fn_GET_WEEKEND_DAYS`; 

DELIMITER $$ 
CREATE FUNCTION `fn_GET_WEEKEND_DAYS`(StartDate DATE, EndDate DATE) RETURNS INT 
BEGIN 
    # declare the variables. 
    DECLARE varDays INT; 

    # create the temprorary table to insert the data in. 
    CREATE TEMPORARY TABLE temp(calendarDate DATE, isWeekend TINYINT(1)); 

    # insert the starting date. 
    INSERT INTO temp VALUES(StartDate, NULL); 

    # insert each day by increment of 1 day untill reached the end date. 
    WHILE (SELECT MAX(CalendarDate) FROM temp) < EndDate DO 
     INSERT INTO temp 
     SELECT ADDDATE(MAX(CalendarDate), INTERVAL 1 DAY), NULL 
     FROM temp; 
    END WHILE; 

    # update the is weekend field depending if the day of week of each row is 1 or 7. (saturday or sunday) 
    UPDATE temp SET isWeekend = CASE WHEN DAYOFWEEK(calendarDate) IN (1, 7) THEN true ELSE false END; 

    # count the date that are weekends. 
    SELECT COUNT(calendarDate) INTO varDays FROM temp WHERE isWeekend = true; 

    # drop the temp table. 
    DROP TEMPORARY TABLE IF EXISTS temp; 

    RETURN varDays; 
END $$ 

TEST:

SELECT fn_GET_WEEKEND_DAYS(CURDATE(), ADDDATE(CURDATE(), INTERVAL 10 DAY)) AS TEST; 

任何幫助和建議將不勝感激。

+0

不是問題,但有一個問題是您在UPDATE語句中有一個misspelt列名。被認爲應該是週末。此外,DAYOFWEEK會返回1至7. – Kickstart

+0

謝謝您指出。 – Sam

回答

0

當前解決方案的快速修復: -

DROP FUNCTION IF EXISTS `fn_GET_WEEKEND_DAYS`; 

DELIMITER $$ 
CREATE FUNCTION `fn_GET_WEEKEND_DAYS`(StartDate DATE, EndDate DATE) RETURNS INT 
BEGIN 
    # declare the variables. 
    DECLARE varDays INT; 
    DECLARE varDate DATE; 

    IF (StartDate > EndDate) THEN 
     SET varDate = StartDate; 
     SET StartDate = EndDate; 
     SET EndDate = varDate; 
    END IF; 

    # create the temprorary table to insert the data in. 
    CREATE TEMPORARY TABLE temp1(calendarDate DATE, isWeekend TINYINT(1)); 

    # insert the starting date. 
    INSERT INTO temp1 VALUES(StartDate, NULL); 

    # insert each day by increment of 1 day untill reached the end date. 
    SET varDate = StartDate; 
    WHILE varDate < EndDate DO 
     INSERT INTO temp1 VALUES(ADDDATE(varDate, INTERVAL 1 DAY), NULL); 
     SELECT MAX(CalendarDate) INTO varDate FROM temp1; 
    END WHILE; 

    # update the is weekend field depending if the day of week of each row is 0 or 1. (saturday or sunday) 
    UPDATE temp1 SET isWeekend = CASE WHEN DAYOFWEEK(calendarDate) = 7 OR DAYOFWEEK(calendarDate) = 1 THEN true ELSE false END; 

    # count the date that are weekends. 
    SELECT COUNT(calendarDate) INTO varDays FROM temp1 WHERE isWeekend = true; 

    # drop the temp1 table. 
    DROP TEMPORARY TABLE IF EXISTS temp1; 

    RETURN varDays; 
END $$ 

大問題是,它是使用臨時表,並試圖插入基於從不能做該臨時表中選擇一個臨時表。它會給出錯誤您不能在同一查詢中多次引用TEMPORARY表。例如,下面不工作:

如果您有日期的有限範圍內,那麼可能很容易在單個SQL語句來完成

編輯

與單個SQL做的一種方式聲明,複製的最大日期範圍爲9999天: -

SELECT SUM(IF(DAYOFWEEK(DATE_ADD('2014-05-02', INTERVAL units.aCnt + tens.aCnt * 10 + hundreds.aCnt * 100 + thousands.aCnt * 1000 DAY)) IN (1,7), 1, 0)) 
FROM (SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) units 
CROSS JOIN (SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) tens 
CROSS JOIN (SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) hundreds 
CROSS JOIN (SELECT 1 AS aCnt UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) thousands 
WHERE '2017-03-01' >= DATE_ADD('2014-05-02', INTERVAL units.aCnt + tens.aCnt * 10 + hundreds.aCnt * 100 + thousands.aCnt * 1000 DAY)