簡體   English   中英

選擇查詢中的MySQL存儲過程循環遞增日期返回最后一個日期

[英]MySQL Stored Procedure Loop Increment Date In Select Query Returns Last Date

我有一個存儲過程,它會增加選擇查詢中的特定日期。 我需要獲取遞增日期變量的當前值以及其他字段。 但是查詢始終僅返回最后一個遞增的日期。 您能告訴我錯誤在哪里嗎?

存儲過程:

CREATE PROCEDURE `IBE_getAvailabilityForRange`(IN firstStayDate DATE, IN lastStayDate DATE)
BEGIN
DECLARE nextDate DATE;
SET nextDate = firstStayDate;
WHILE nextDate <= lastStayDate DO
SELECT nextDate as stayDate, Room_type, No_of_room, ArrivalDate, DepartDate, state FROM reservation_temp WHERE Reservation_is_done = 1 AND state != 0 AND ArrivalDate <= nextDate AND DepartDate > nextDate;
SET nextDate = DATE_ADD(nextDate, INTERVAL 1 DAY);
END WHILE;
END

結果在call IBE_getAvailabilityForRange('2019-02-25', '2019-02-27');

存儲過程輸出

[編輯]我需要它來輸出2019-02-25、2019-02-26、2019-02-27的結果。 目前,它只為我提供2019-02-27的結果。

[編輯:使用GROUP BY和SUM編輯存儲過程]

BEGIN
DECLARE nextDate DATE;
SET nextDate = firstStayDate;
WHILE nextDate <= lastStayDate DO
SELECT nextDate as stayDate, Room_type, SUM(No_of_room), ArrivalDate, DepartDate, state FROM reservation_temp WHERE Reservation_is_done = 1 AND state != 0 AND ArrivalDate <= nextDate AND DepartDate > nextDate GROUP BY stayDate, Room_type;
SET nextDate = DATE_ADD(nextDate, INTERVAL 1 DAY);
END WHILE;

我建議您不要使用存儲過程來膨脹簡單的查詢:

如果您在某個過程中循環存儲過程,則查詢的效率可能非常低。

因此,此過程可以替換為單個查詢:

SELECT Room_type, No_of_room, ArrivalDate, DepartDate, state
FROM reservation_temp
WHERE Reservation_is_done = 1
      AND state != 0
      AND ArrivalDate <= {arrivedate}
      AND {enddate} < DepartDate

Reservation_temp真的是臨時表嗎?

如我的評論中所述,問題是由SELECT語句在增加nextDate之前迭代一天的行集引起的。 結果,您的過程每天將執行多個SELECT語句,並從上次執行的查詢返回結果。

即:

SELECT day1;
SELECT day2;

要以我認為您希望實現的方式解決此問題,一種方法是使用臨時表存儲每天檢索到的記錄,直到處理完每一天為止,然后從臨時表中檢索值。

但是,您需要為ArrivalDate,DepartDate和state更好地定義GROUP BY列。 由於MySQL 5.7+默認情況下啟用了ONLY_FULL_GROUP_BY ,因此會出錯。 我已經使用MINMAX並將state添加到分組中以防止錯誤。

或者,在列上顯式使用ANY_VALUE() ,以允許MySQL在每個未聚合的組中選擇一個值。 [原文如此]

CREATE PROCEDURE `IBE_getAvailabilityForRange`(IN firstStayDate DATE, IN lastStayDate DATE)
BEGIN
DECLARE nextDate DATE;

DROP TEMPORARY TABLE IF EXISTS tmp_stays;
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_stays(
    stayDate DATE,
    Room_type INT(10),
    rooms INT(10),
    ArrivalDate DATE,
    DepartDate DATE,
    state INT
);

SET nextDate = firstStayDate;
WHILE nextDate <= lastStayDate DO
    INSERT tmp_stays
    SELECT
       nextDate, 
       Room_type, 
       SUM(No_of_room), 
       MIN(ArrivalDate), 
       MAX(DepartDate), 
       state
    FROM reservation_temp 
    WHERE Reservation_is_done = 1 
    AND state != 0 
    AND ArrivalDate <= nextDate 
    AND DepartDate > nextDate 
    GROUP BY nextDate, Room_type, state;

    SET nextDate = DATE_ADD(nextDate, INTERVAL 1 DAY);
END WHILE;

SELECT * FROM tmp_stays;
DROP TEMPORARY TABLE IF EXISTS tmp_stays;
END

對於數據集(請注意,ID 1和ID 2具有不同的DepartDate值)

reservation_temp
---
| id | Room_type | state | No_of_room | ArrivalDate | DepartDate | Reservation_is_done | 
| ---: | ---: | ---: | ---: | --- | --- | ---: | 
| 1 | 1 | 1 | 1 | 2019-01-01 | 2019-01-02 | 1 | 
| 2 | 1 | 1 | 1 | 2019-01-01 | 2019-01-03 | 1 | 
| 3 | 1 | 1 | 1 | 2019-01-03 | 2019-01-04 | 1 | 
| 4 | 1 | 1 | 1 | 2019-01-04 | 2019-01-04 | 1 | 
| 5 | 1 | 1 | 1 | 2019-01-04 | 2019-01-05 | 1 | 

結果

/* CALL IBE_getAvailabilityForRange('2019-01-01', '2019-01-05'); */

tmp_stays
---
| stayDate | Room_type | rooms | ArrivalDate | DepartDate | state | 
| --- | ---: | ---: | --- | --- | ---: | 
| 2019-01-01 | 1 | 2 | 2019-01-01 | 2019-01-03 | 1 | 
| 2019-01-02 | 1 | 1 | 2019-01-01 | 2019-01-03 | 1 | 
| 2019-01-03 | 1 | 1 | 2019-01-03 | 2019-01-04 | 1 | 
| 2019-01-04 | 1 | 1 | 2019-01-04 | 2019-01-05 | 1 | 

您可能需要看一下此討論: 從日期范圍生成天數

使用討論中的一些查詢,您可以獲取日期范圍內的日期列表。 然后,僅內部/左側加入您的數據即可獲得所需的內容。

使用我的實現(我有helper table +視圖,但這不是必需的),生成的查詢看起來像這樣:

SELECT
      Dates.d
    , reservation_temp.*
FROM
    global.Dates
    INNER JOIN reservation_temp ON (
            Reservation_is_done = 1
        AND state != 0
        AND ArrivalDate <= Dates.d
        AND DepartDate > Dates.d
    )
WHERE
    Dates.d BETWEEN firstStayDate AND lastStayDate

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM