2017-02-27 87 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)