我的表格中有一些数据(tb1
):
PK datetime1 datetime2 grp
--------------------------------------------------------
1 2016-01-01 00:30:10 2016-01-01 00:33:10 1
2 2013-01-01 00:30:10 2013-01-01 00:34:10 2
我正在尝试根据datetime1,datetime2和location查找事件数。
所以这是我的问题:
select count(*), datetime1, datetime2, grp
from tb1
group by datetime1, datetime2, grp
这里没问题。
在某种程度上,我想基于以下方式找到计数:
当两个连续的(可以通过引导函数实现)行的datetime1差异小于1秒并且两个连续行之间的datetime2差异小于1秒,并且grp。
我可以使用lead来查找两个连续行之间的差异,但不知道如何在此处应用count函数来按两个连续行之间的时间相似性进行分组。
为了使这更简单,我正在寻找这样的东西:
如果
select
count(*), grp, ....
from
tb1
where
datediff(s, lead(datetime1, 1, 1) over (partition by grp order by datetime1)) = 1
and datediff(s, lead(datetime2, 1, 1) = 1 over (partition by grp order by datetime2) = 1
group by
lead(datetime1, 1, 1) over (partition by grp order by datetime1),
lead(datetime2, 1, 1) over (partition by grp order by datetime2),
grp
如果需要进一步澄清,请告诉我。
答案 0 :(得分:2)
我生成了一些示例数据。检查这是否是您要找的。我在代码中添加了必要的注释。查询可以更简洁,但我想尽可能多地解释每一步:
declare @table table (PK int, datetime1 datetime, datetime2 datetime, grp int)
insert into @table values
(1, '2016-01-01 00:30:14.000', '2016-01-01 00:33:15.000', 1),
(2, '2016-01-01 00:30:10.232', '2016-01-01 00:33:10.000', 1),
(3, '2016-01-01 00:30:10.111', '2016-01-01 00:33:10.234', 1),
(4, '2016-01-01 00:30:12.000', '2016-01-01 00:33:15.000', 2),
(5, '2016-01-01 00:30:10.000', '2016-01-01 00:33:10.234', 2),
(6, '2016-01-01 00:30:10.222', '2016-01-01 00:33:10.000', 2)
select min(pk), min(datetime1), count(*) from (
--in this query, based on differences, we will generate grouping column called IsClose
select *, case when (diff1 <= 1000 and diff2 <= 1000) or (diff3 <= 1000 and diff4 <= 1000) then 1 else 0 end [IsClose] from (
--this query gives to additionals columns with absolute differences between consecutive rows ordered by PK column
select *,
abs(datediff(ms, datetime1, lag(datetime1) over (order by pk))) [diff1],
abs(datediff(ms, datetime2, lag(datetime2) over (order by pk))) [diff2],
abs(datediff(ms, datetime1, lead(datetime1) over (order by pk))) [diff3],
abs(datediff(ms, datetime2, lead(datetime2) over (order by pk))) [diff4]
from @table
) [a]
) [a] group by grp, IsClose
答案 1 :(得分:2)
这是基于int的,但同样的方法适用于datetime
declare @T table (pk int identity primary key, val int);
insert into @T values ('1'), ('9'), ('9'), ('11'), ('2'), ('2'), ('3'), ('5'), ('7'), ('8');
select tt.pk, tt.val
, sum(ll) over (order by val, pk) as grp
from ( select *
, case when lag(val,1) over (order by val, pk) is null
or val - lag(val,1) over (order by val, pk) <= 1 then 0
else 1
end as ll
from @T t
) tt
order by val, pk;
pk val grp
----------- ----------- -----------
1 1 0
5 2 0
6 2 0
7 3 0
8 5 1
9 7 2
10 8 2
2 9 2
3 9 2
4 11 3