SQL Server:在X分钟内合并开始/停止记录时选择

时间:2018-10-01 17:07:38

标签: sql sql-server

我有两个SQL Server表:

大师

 Id   INT IDENTITY
 Day  DATETIME
 User INT

详细信息

 Id         INT IDENTITY
 Fk_Id      INT           ( << foreign Key to Master Id )
 UsageStart DATETIME
 UsageStop  DATETIME

对于所有用户,在给定范围内的几天内,我想返回给定一周的以下活动:

 User, Day, UsageStart, UsageStop

但是,在用户停止然后在10分钟内再次开始使用的地方,我需要合并这些记录。例如。以下:

  User, Day, UsageStart, UsageStop
  199   Tue  14:55       15:25
  199   Tue  15:25       15:27
  199   Tue  15:32       15:45 
  199   Tue  18:12       18:16 

我需要显示以下内容(合并前三个记录):

  User, Day, UsageStart, UsageStop
  199   Tue  14:55       15:45
  199   Tue  18:12       18:16 

我知道如何使用类似于以下的查询来查找将受到影响的记录:

 SELECT * 
   FROM dbo.Detail d 
  WHERE fk_Id in (SELECT Id
                    FROM Master
                   WHERE Day between '1/1/18' and '1/5/18')  
    AND EXISTS(SELECT 1 
                 FROM Detail d2 
                WHERE d2.Fk_Id = d.Fk_Id 
                  and d.Id <> d2.Id 
                  and datediff(MINUTE,d.UsageStop,d2.UsageStart) < 10)

但是我不确定实际创建查询以显示请求的最佳方式(在10分钟内合并结果。有没有简单有效的方法来实现此目的,我没有看到吗?感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

使用滞后获取上一条记录,然后使用逻辑确定组的起始位置,并使用累积和来分配组。然后,聚合:

select usr, min(usage_start), max(usage_stop)
from (select d.*, 
             sum(case when prev_us >= dateadd(minute, -10, usage_start) 
                      then 1 else 0 end) over (partition by user order by usage_start) as grp
      from (select d.*,
                   lag(usage_stop) over (partition by user order by usage_start) as prev_us
            from detail d
           ) d
     ) d
group by user, grp;
相关问题