简体   繁体   English

MySQL联接-检查具有某些列值的不存在的行

[英]Mysql join - check for non existant rows having certain column values

I have a restaurants table and a bookings table. 我有一个restaurants表和一个bookings表。 Each booking stores a date, number of persons, and one of 3 time slots ( event_time ). 每个预订都存储日期,人数和3个时隙之一( event_time )。 An example row: 示例行:

id | restaurant_id |         date         | number_of_persons | event_time
7        2           2019-09-12 00:00:00            15               2

I want to return all restaurants that has free seats bookable for any event_time on a certain date. 我想退回所有可以预订特定日期任意event_time的免费座位的餐厅。

Restaurants with no bookings are returned using left join. 没有预订的餐厅使用left联接返回。 I can get bookings with the join and do SUM(number_of_persons) and check if max capacity has been met for each event_time that has bookings. 我可以通过加入进行预订,并进行SUM(number_of_persons)并检查是否已满足每个具有预订的event_time的最大容量。 The problem is that any event_time having 0 bookings is not included in the result (since it is non existant), so it doesn't count. 问题在于结果中不包含任何具有0个预订的event_time(因为它不存在),因此不计算在内。

The current query excludes restaurants which are fully booked for the event_times which has bookings. 当前查询不包括已预订的event_times预订满的餐厅。 So if event_time 1 and 2 are fully booked, and event_time 3 is free and bookable, that restaurant is still excluded (wrongly). 因此,如果event_time 1和2已被预订event_time ,而event_time 3是免费且可预订的,则该餐厅仍将被排除(错误地)。

Here is the current query: 这是当前查询:

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

I have a fiddle here. 我在这里摆弄

The logic I think is needed is: Return restaurants which have bookings and: 我认为需要的逻辑是:退回有预订的餐厅,并且:

  • does not have bookings for all the three event_times 这三个event_times都没有预订

or 要么

  • have bookings for all three event_times and there are still available seats. 预订了所有三个event_times 并且仍有可用座位。

But I don't know how to implement it. 但是我不知道如何实现它。 I appreciate any help! 感谢您的帮助!

You need to assign event_time 1,2,3 for every place before left join with booking_summerise then only it gives results for every event. 您需要为每个位置分配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`

DEMO DEMO

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM