我有一个restaurants
表和一个bookings
表。每个预订都存储日期,人数和3个时隙之一(event_time
)。示例行:
id | restaurant_id | date | number_of_persons | event_time
7 2 2019-09-12 00:00:00 15 2
我想退回所有可以在特定日期预订任何event_time的免费座位的餐厅。
使用left
连接返回没有预订的餐馆。
我可以通过加入进行预订,并执行SUM(number_of_persons)
并检查是否已满足每个具有预订的event_time的最大容量。 问题:结果中不包含任何具有0个预订的event_time(因为它不存在),因此不计入。
当前查询不包括已预订的event_times预订满的餐厅。因此,如果event_time
1和2已被预订满,而event_time
3是免费且可预订的,则该餐厅仍然(错误地)被排除在外。
这是当前查询:
select restaurants.id, `restaurants`.title,
number_of_seats_max,
num_persons_booked,
number_of_seats_max - num_persons_booked AS free_seats_left,
event_time
from `restaurants`
left join ( select `restaurant_id`, `b`.`event_time`,
SUM(b.number_of_persons) as num_persons_booked
from `bookings` as `b`
where `event_date` = "2019-9-12"
group by `b`.`event_time`, `restaurant_id`
order by num_persons_booked
) as `bookings_summaries`
on `restaurants`.`id` = `bookings_summaries`.`restaurant_id`
having number_of_seats_max - num_persons_booked > 0 // <-- not fully booked
or num_persons_booked IS NULL //<-- no bookings
我在这里有一个fiddle。
我认为需要的逻辑是:退回有预订的餐厅,并且:
或
但是我不知道如何实现它。感谢您的帮助!
答案 0 :(得分:1)
您需要在每个地方分配event_time 1,2,3,然后再与booking_summerise左联接,然后才为每个事件提供结果。
select restaurants.id, `restaurants`.title,
number_of_seats_max,
restaurants.event_time,
IFNULL(num_persons_booked,0) AS num_persons_booked,
number_of_seats_max - IFNULL(num_persons_booked,0) AS free_seats_left
from ((select *,("1") AS event_time from restaurants) UNION ALL (select *,("2") AS event_time from restaurants) UNION ALL (select *,("3") AS event_time from restaurants)) AS restaurants
left join ( select `restaurant_id`, `b`.`event_time`, SUM(b.number_of_persons) as num_persons_booked
from `bookings` as `b`
where `event_date` = "2019-9-12"
group by `b`.`event_time`, `restaurant_id`
order by num_persons_booked
) as `bookings_summaries`
on `restaurants`.`id` = `bookings_summaries`.`restaurant_id` AND
`restaurants`.`event_time` = `bookings_summaries`.`event_time`
having number_of_seats_max - num_persons_booked > 0
or num_persons_booked IS NULL
ORDER BY `restaurants`.`id`