2017-02-27 18 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ステートメントに誤った列名があります。 isWeeked isWeekendにする必要があります。また、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文で行うのに十分簡単に​​日付の限られた範囲を持っている場合は

EDIT

単一の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) 
関連する問題