使用SQL查找可用时隙

时间:2013-11-27 16:15:00

标签: php mysql sql

我在SO上找到了answer关于在数据库中查找可用时隙的常见问题。该查询就像一个魅力,但如果我添加一个在alredy添加事件之前启动的新事件,它就会失败。在这种情况下,输出的顺序是错误的。答案中有一个sqlFiddle示例,我刚刚在架构中添加了一个新行:

insert into bookingEvents values (null, '2013-05-12 05:11:00', 15);

正如您所看到的,事件的日期早于上一次插入事件的日期之前( timeBooked 不再按顺序排列)。也许我试图在查询中加入过多的逻辑,如果是这样,那我怎么能用PHP来处理这个问题呢?

修改

可能我应该首先展平时间戳,然后对结果执行查询。我找到something来缩小时间戳,但我需要帮助来合并两个查询并获得针对生产优化的内容

1 个答案:

答案 0 :(得分:1)

为了保持我的理智,我创建了一个视图如下......

CREATE VIEW v_bookingevents AS 
     SELECT id
          , timebooked startdate
          , timebooked + INTERVAL duration MINUTE enddate 
       FROM bookingevents 
      ORDER 
         BY startdate;

则...

SELECT a.enddate 'Available From'
         , MIN(b.startdate) 'To'
  FROM 
     ( 

      SELECT DISTINCT
             COALESCE(LEAST(x.startdate,y.startdate),x.startdate) startdate
           , COALESCE(GREATEST(x.enddate,y.enddate),x.enddate) enddate 
        FROM v_bookingevents x 
        LEFT 
        JOIN v_bookingevents y 
          ON y.id <> x.id
         AND y.startdate < x.enddate 
   AND y.enddate > x.startdate
   UNION
   SELECT '2013-05-12 00:00:00' 
               , '2013-05-12 00:00:01' 

     ) a
  JOIN 
     (      
  SELECT DISTINCT
         COALESCE(LEAST(x.startdate,y.startdate),x.startdate) startdate
       , COALESCE(GREATEST(x.enddate,y.enddate),x.enddate) enddate 
    FROM v_bookingevents x 
    LEFT 
    JOIN v_bookingevents y 
      ON y.id <> x.id
     AND y.startdate < x.enddate 
   AND y.enddate > x.startdate

        UNION
       SELECT '2013-05-15 00:00:00' 
            ,'2013-05-15 00:00:01' 
     ) b 
    ON b.startdate > a.enddate
 GROUP 
    BY a.enddate
HAVING a.enddate < MIN(b.startdate); 

http://sqlfiddle.com/#!2/e67b47/1

显然,你可以在没有视图的情况下重写它 - 我发现很难读出所有那些“+ INTERVAL”位。