【问题标题】:MYSQL finding time span between two dates/timesMYSQL 查找两个日期/时间之间的时间跨度
【发布时间】:2012-12-11 20:37:08
【问题描述】:

我有一个表有两个字段 dt(DateTime) 和 isblocked(Bit)

我一直在尝试做的是找到两个日期/时间之间的时间跨度,其中有 45 分钟连续空闲 - 基于开始日期/时间。

例如:根据上表,使用 2012-12-11 13:30:00' 作为我的开始日期。 我需要这样的值:

2012-12-11 15:30:00
2012-12-11 16:45:00

我尝试了一些最小和最大查询,例如:

SELECT MIN(dt), isbooked
FROM booking
WHERE dt >= '2012-12-11 13:30:00' AND isbooked = 1
GROUP BY dt
LIMIT 1;

但我似乎无法将正确的结构组合在一起。如果需要更多信息,请告诉我。

【问题讨论】:

  • 您如何知道预订的时长?是否只是约定每次为 15 分钟,每次预订是否“有效”直到下一次开始,还是有另一列指示预订的持续时间?
  • 您能否以复制粘贴友好的格式发布示例数据?
  • 嗨,马特,感谢您抽出宝贵时间阅读我的问题,每次预订时间可能是 30 分钟,或者每隔 30 或 45 分钟间隔一次,这就是为什么我将其设置为 15 分钟。

标签: mysql sql datetime


【解决方案1】:

在 MySQL 中,您可以使用相关子查询来做到这一点:

select min(b.dt) as StartTime, NotBookedTime as EndTime
from (select b.*,
             (select min(b2.dt) from booking b2 where b2.dt >= b.dt and b2.isbooked = 1
             ) as NotBookedTime
      from booking b
     ) b
where b.isbooked = 0
group by NotBookedTime
having date_add(min(b.dt), interval 45 minute) <=  NotBookedTime

它的作用是找到每条记录的第一个预定间隔,并记住时间。然后它会找到第一个预定的间隔,并检查差异何时为 45 分钟或更大。

【讨论】:

  • 嗨,戈登,感谢您的回答!我会试一试并尽快报告我知道这将比基本查询多一点..但我知道你做了什么,它非常酷..
  • 唯一的语法错误是我写了45 minutes而不是45 minute。查询确实有效。
【解决方案2】:

这也应该有效:

SELECT d.dt
FROM (
  SELECT
    t1.dt,
    MIN(case when t2.isBooked then t2.dt end) AS next_booked,
    MAX(case when not t2.isBooked then t2.dt end) as max_unbooked
  FROM times t1 INNER JOIN times t2 ON t1.dt < t2.dt
  WHERE t1.isBooked =0
  GROUP BY t1.dt
) d
WHERE
  timediff(next_booked,d.dt)>='00:45:00' or
  (next_booked is null and timediff(max_unbooked,d.dt)>='00:30:00')

取决于你所追求的,也可以这样简化:

SELECT d.dt
FROM (
  SELECT
    t1.dt,
    MIN(t2.dt) as next_booked
  FROM times t1 left  JOIN times t2 ON t1.dt < t2.dt and t2.isBooked=1
  WHERE t1.isBooked =0
  GROUP BY t1.dt
) d
WHERE timediff(d.next_booked, d.dt)>='00:45:00'
      or d.next_booked is null
GROUP BY d.next_booked

【讨论】:

    【解决方案3】:

    看看这个SQLFiddle

    SELECT min(b.dt) AS StartTime, NotBookedTime AS EndTime
    FROM (SELECT b.*,
            (SELECT min(b2.dt) FROM DT b2 
               WHERE b2.dt >= b.dt AND b2.isBooked = 1
             ) AS NotBookedTime
         FROM DT b
        ) b
    WHERE b.isBooked = 0
    GROUP BY NotBookedTime
    HAVING EndTime is not null
    

    【讨论】:

      【解决方案4】:

      你可以使用变量:

      set @tp=now();
      SELECT @tp:=dt as dt,isbooked FROM booking WHERE 
          dt >= addtime(@tp,'00:45:00') AND isbooked = 1
          ORDER BY dt;
      

      @TP 将采用上一个所选日期的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        • 2018-02-13
        • 1970-01-01
        • 2012-06-03
        • 2021-01-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多