0

我在几个地方寻找过这个,但不一定找到正确的答案。

我正在尝试查询给定时间范围内的可用提供程序。我有一列包含所有带有 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 个条件语句来弄清楚。

  1. :start(of the new booking) BETWEEN da.date_start AND da.date_end
  2. :end(of the new booking) BETWEEN da.date_start AND da.date_end
  3. da.date_start BETWEEN :start AND :end (另一个预订不在新预订的开头或结尾)

这似乎效率很低,但我找不到更好的方法。当然我可以通过索引来提高效率,但是有没有更好的方法来执行这个操作。这是我项目的一个核心问题,我认为这可能是许多人已经面临并将继续面临的问题。再次感谢!

4

2 回答 2

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
于 2012-05-02T16:49:19.037 回答
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

不需要子查询!让我知道您是否需要有关索引的帮助以使该查询执行良好。

于 2012-05-02T16:48:25.843 回答