在Postgresql中检查重叠预订

时间:2018-04-16 15:50:04

标签: sql postgresql

我有一张可以租用汽车的预订表。有多辆车和多个预订。我想创建一个查询来检查预订中的任何重叠(预订同一辆车的预订和日期冲突)。

目前我有以下查询:

SELECT bi.id, car_id, booking_id 
from booking_bookingitem bi 
WHERE (
SELECT count(*) FROM booking_bookingitem bt 
WHERE (
date_start - interval '1 days', date_end + interval '1 days'
) OVERLAPS (now(), now() + INTERVAL '30 days') 
AND bt.car_id = bi.car_id) > 1 
ORDER BY car_id, booking_id

我在开始(date_start)和结束(date_end)的任一侧添加了1天的偏移量以允许汽车返回,清理等.30天的间隔是在将来30天检查预订。

我想我已经接近但我在测试时遇到了一些异常。

有人能发现我做错了什么,或者有更好的方法吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

您应该将每一行相互比较,并在单个结果行中显示两个重叠的行,例如:

with booking_bookingitem(car_id, booking_id, date_start, date_end) as (
values
    (1, 1, '2018-05-01'::date, '2018-05-03'::date),
    (1, 2, '2018-05-05', '2018-05-07'),
    (1, 3, '2018-05-11', '2018-05-13'), -- 
    (1, 4, '2018-05-14', '2018-05-16'), -- collision
    (1, 5, '2018-05-21', '2018-05-23')
)

select 
    bi.car_id, 
    bi.booking_id, bi.date_start, bi.date_end,
    bt.booking_id, bt.date_start, bt.date_end
from booking_bookingitem bi 
join booking_bookingitem bt 
on (bi.date_start- 1, bi.date_end+ 1) overlaps (bt.date_start- 1, bt.date_end+ 1) and bi.booking_id < bt.booking_id
where bi.date_start between current_date and current_date+ 30


 car_id | booking_id | date_start |  date_end  | booking_id | date_start |  date_end  
--------+------------+------------+------------+------------+------------+------------
      1 |          3 | 2018-05-11 | 2018-05-13 |          4 | 2018-05-14 | 2018-05-16
(1 row)