我在几个地方寻找过这个但不一定找到正确的答案。
我正在尝试查询给定时间范围内的可用提供商。我有一个列,其中包含所有带有date_start和date_end的旧预订。基本上,如果我想预订,我需要确保我的提供商可用。到目前为止,查询的工作原理如下:
SELECT a.provider a
FROM l_provider_zip a
(several inner Joins and conditions)
WHERE a.zip = :zip
AND a.provider_id
NOT IN (
SELECT da.provider_id
FROM booking da
WHERE da.provider_id IS NOT NULL
AND (
( :start BETWEEN da.date_start AND da.date_end)
OR ( :end BETWEEN da.date_start AND da.date_end)
OR ( da.date_start BETWEEN :start AND :end )
)
)
我担心的是,为了找出可用于新预订的提供商,我需要确保新预订不会与其他预订冲突。在这里,我有3个条件陈述来解决它。
这似乎效率很低但我找不到更好的方法。当然,我可以通过索引使其更有效,但是有更好的方法来执行此操作。这对我的项目来说是一个中心问题,我认为这可能是许多人面临的问题,并将继续面对。再次感谢!
答案 0 :(得分:2)
如果我理解了您的问题,那么您正在寻找可用于此预订的提供商,即那些没有预订与此预订相冲突的提供商。因此,要查找与此预订相冲突的所有预订,您需要查找预订
- where the booking start date is on or before the new booking end date, and
- where the booking end date is on or after the new booking start date
因此,您的子查询将转换为
SELECT da.provider_id
FROM booking da
WHERE da.provider_id IS NOT NULL
AND da.date_start <= :end
AND da.date_end >= :start
答案 1 :(得分:1)
我会将提供商加入到指定日期范围内的预订中,然后将这些提供商排除在外:
/* Select all providers */
SELECT *
FROM l_provider_zip p
/* Providers with bookings that start in the middle of our date range are busy */
LEFT JOIN booking b1
ON b1.provider_id = p.provider_id
AND b1.date_start BETWEEN :start AND :end
/* Providers with bookings that end in the middle of our date range are busy */
LEFT JOIN booking b2
ON b2.provider_id = p.provider_id
AND b2.date_end BETWEEN :start AND :end
/* Exclude those providers with bookings in our date range */
WHERE b1.provider_id IS NULL
AND b2.provider_id IS NULL
不需要子查询!如果您需要索引方面的帮助,请告诉我,以使此查询运行良好。