我有一个存储过程,该过程在选择查询中增加特定日期。我需要获取递增日期变量的当前值以及其他字段。但是查询始终仅返回最后一个递增的日期。您能告诉我错误在哪里吗?。
存储过程:
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;
答案 0 :(得分:0)
我建议您不要使用存储过程来膨胀简单的查询:
如果您在存储过程中循环访问某个内容,查询可能会非常低效。
因此,此过程可以用一个查询替换:
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真的是临时表吗?
答案 1 :(得分:0)
如我的评论中所述,此问题是由dgof
语句在增加SELECT
之前遍历一天的行集引起的。结果,您的过程每天将执行多个nextDate
语句,并从上次执行的查询返回结果。
即:
SELECT
要以我认为您希望实现的方式解决此问题,一种方法是使用临时表存储每天检索到的记录,直到处理完每一天为止,然后从临时表中检索值。 / p>
但是,您需要为ArrivalDate,DepartDate和state更好地定义
SELECT day1; SELECT day2;
列。 由于MySQL 5.7+默认启用了GROUP BY
,因此会出错。我已使用ONLY_FULL_GROUP_BY
,MIN
并将MAX
添加到分组中以防止出错。或者在列上显式使用
state
,以允许MySQL在每个组中选择一个尚未聚合的值。 [sic]
ANY_VALUE()
使用的数据集(请注意,ID 1和2具有不同的DepartDate值)
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
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 |
答案 2 :(得分:0)
您可能需要查看以下讨论: generate days from date range
使用讨论中的一些查询,您可以获取日期范围内的日期列表。然后,只需将内部/左侧的数据连接起来,便可以得到想要的东西。
使用我的实现(我有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