记一次SQL时间序列分组汇总的问题

Posted dpwow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次SQL时间序列分组汇总的问题相关的知识,希望对你有一定的参考价值。

实现日期间隔分组, 间隔小于等于3s的数据为一组,数据源如下

create table #tmptable(id nvarchar(20),dd date ,dt  datetime)
go
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:01‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:02‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:03‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:04‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:05‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:06‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:07‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:09‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:11‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:12‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:15‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:19‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:20‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:24‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:25‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:26‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:27‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:28‘)
insert #tmptable values(‘1‘,‘2010-1-1‘,‘2010-1-1 00:00:29‘)
insert #tmptable values(‘1‘,‘2010-1-2‘,‘2010-1-2 00:00:36‘)
insert #tmptable values(‘1‘,‘2010-1-2‘,‘2010-1-2 00:00:37‘)
insert #tmptable values(‘1‘,‘2010-1-2‘,‘2010-1-2 00:00:48‘)
insert #tmptable values(‘1‘,‘2010-1-2‘,‘2010-1-2 00:00:59‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:09‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:11‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:12‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:15‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:19‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:20‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:24‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:25‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:26‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:27‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:28‘)
insert #tmptable values(‘2‘,‘2010-1-1‘,‘2010-1-1 00:00:29‘)
insert #tmptable values(‘2‘,‘2010-1-2‘,‘2010-1-2 00:00:36‘)
insert #tmptable values(‘2‘,‘2010-1-2‘,‘2010-1-2 00:00:37‘)
insert #tmptable values(‘2‘,‘2010-1-2‘,‘2010-1-2 00:00:48‘)
insert #tmptable values(‘2‘,‘2010-1-2‘,‘2010-1-2 00:00:59‘)

go

  检测数据断点

;WITH MyList AS(SELECT ROW_NUMBER() OVER(ORDER BY id,dd, dt asc) RN,T.*  FROM #tmptable T) 
select a.RN,a.id,a.dd,a.dt,
	CASE WHEN b.dt IS null then 0
		ELSE DATEDIFF(ss,b.dt,a.dt) END as secspan,
	CASE WHEN b.dt IS null or DATEDIFF(ss,b.dt,a.dt) <= 3 THEN 1 ELSE 0
	 END as flag
	 --into #TMP1
 from MyList a left join MyList b
on b.RN = a.RN - 1 and a.id = b.id and a.dd  = b.dd

 技术分享图片

 

聚合时间段

select id,dd,MIN(dt) as sdt,MAX(dt) as edt from 
(
	select ss=(select SUM(flag) from #TMP1 where dt <= a.dt and id = a.id and dd = a.dd)
	,* from #TMP1 a where id= a.id and dd = a.dd
) a
GROUP BY (RN - ss),id,dd

 技术分享图片

 

 

以上是关于记一次SQL时间序列分组汇总的问题的主要内容,如果未能解决你的问题,请参考以下文章

记一次MySQL Group by 的坑

记一次查询性能优化,原30s+,现0.5s~20s

记一次伪*sql查询结果不一致的

PHP代码审计 | 记一次CMS代码审计

优化器Bug?记一次慢SQL问题分析过程

记一次SQL调优