【问题标题】:Grouping consecutive time intervals in SQL在 SQL 中对连续的时间间隔进行分组
【发布时间】:2015-12-18 15:04:14
【问题描述】:

我有这样的事情

+------+-----+-----------+---------+
| Room | Day | StartTime | EndTime |
+------+-----+-----------+---------+
| 1    | 1   | 08:00     | 09:00   |
+------+-----+-----------+---------+
| 1    | 1   | 09:00     | 10:00   |
+------+-----+-----------+---------+
| 1    | 1   | 13:00     | 14:00   |
+------+-----+-----------+---------+
| 2    | 2   | 07:00     | 08:00   |
+------+-----+-----------+---------+

我想按房间、日期和时间间隔进行分组,但只能按连续的时间间隔进行分组,例如:

+------+-----+-----------+---------+
| Room | Day | StartTime | EndTime |
+------+-----+-----------+---------+
| 1    | 1   | 08:00     | 10:00   |
+------+-----+-----------+---------+
| 1    | 1   | 13:00     | 14:00   |
+------+-----+-----------+---------+
| 2    | 2   | 07:00     | 08:00   |
+------+-----+-----------+---------+

我有这段代码,但我不满意,因为它也在分组间隙并抛出以下结果:

SELECT
sd.Cod_Room,
sd.Cod_Day,
MIN(bd.StartTime) as StartTime,
MAX(bd.EndTime) as EndTime
FROM
Schedule.ScheduleDetail AS sd
INNER JOIN Schedule.BlockDetail AS bd ON sd.Cod_BlockDetail = bd.Cod_BlockDetail
GROUP BY
sd.Room, sd.Day

+------+-----+-----------+---------+
| Room | Day | StartTime | EndTime |
+------+-----+-----------+---------+
| 1    | 1   | 08:00     | 14:00   |
+------+-----+-----------+---------+
| 2    | 2   | 07:00     | 08:00   |
+------+-----+-----------+---------+

我正在阅读有关 Lead() 和 lag() 的信息,但它花费的时间比我想象的要多。 感谢您的帮助

【问题讨论】:

  • 你用的是什么版本的sql server?
  • @JamieD77 我正在使用 2014

标签: sql sql-server time intervals


【解决方案1】:

您可以通过识别重叠的组然后累积该值来定义一个组来做到这一点。以下假设 SQL Server 2012+:

with t as (
      select sd.Cod_Room, sd.Cod_Day, bd.StartTime, bd.EndTime
      from Schedule.ScheduleDetail sd INNER JOIN
           Schedule.BlockDetail bd
           ON sd.Cod_BlockDetail = bd.Cod_BlockDetail
     )
select cod_room, cod_day,
       min(startTime) as startTime, max(endTime) as endTime
from (select t.*,
             sum(IsStart) over (partition by cod_room, cod_day order by StartTime) as grp
      from (select t.*, 
                   (case when StartTime = lag(EndTime) over (partition by cod_room, cod_day order by StartTime)
                         then 0 else 1
                    end) as IsStart
            from t
           ) t
     ) t
group by cod_room, cod_day, grp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多