需要计算一对对象在给定时间间隔内一起出现的次数。如果相同的对象在5分钟跨度内被多次列出,则应该计为一次出现。我有代码来计算每个单独的事件对,但无法弄清楚如何对在5分钟内出现的多个事件进行分组:
if object_id(N'a', N'U') IS NOT NULL
DROP TABLE a;
GO
create table a (name varchar (20), dt datetime);
go
create index i1 on a (name);
insert a
values
('A', '20140101 13:00:00.000')
, ('A', '20140101 13:00:01.000')
, ('A', '20140101 13:00:02.000')
, ('B', '20140101 13:01:00.000')
, ('C', '20140101 13:01:30.000')
, ('D', '20140101 13:02:00.000')
, ('E', '20140101 13:02:30.000')
, ('B', '20140201 13:00:00.000')
, ('C', '20140201 13:01:00.000')
, ('K', '20140201 13:01:30.000')
, ('L', '20140201 13:02:00.000')
, ('M', '20140201 13:02:30.000')
, ('A', '20140201 13:03:00.000')
, ('A', '20140301 13:00:00.000')
, ('D', '20140301 13:01:00.000')
, ('E', '20140301 13:01:30.000')
, ('P', '20140301 13:02:00.000')
, ('R', '20140301 13:02:30.000')
, ('Q', '20140301 13:03:00.000')
, ('A', '20140401 13:00:00.000')
, ('X', '20140401 13:01:00.000')
, ('Y', '20140401 13:01:30.000')
, ('Z', '20140401 13:02:00.000')
GO
with prox (FirstName, SecondName)
AS (select a.name, b.name
from a
cross join a AS b
where a.name < b.name
and ABS(DATEDIFF(mi, a.dt, b.dt)) < 5)
select FirstName, SecondName, count(*)
from prox
group by FirstName, SecondName
having count(*) > 1
order by 1, 2
在我的例子中,AB,AC,AD和AE的计数应该是2而不是4,因为在第一组中,A在5分钟内出现3次,应该计数一次而不是3次。
答案 0 :(得分:1)
你可以创建另一个cte,只获得至少5分钟的值,然后再使用你的cte
WITH cte
AS (SELECT
name,
dt
FROM
a a1
WHERE
dt = (SELECT MIN (dt) FROM a a2 WHERE a2.name = a1.name
)
UNION ALL
SELECT
a1.name,
a1.dt
FROM
a a1
JOIN cte a2 ON a1.name = a2.name
AND a1.dt > DATEADD(minute,5,a2.dt)
),
cteGroup
AS (SELECT DISTINCT
name,
dt
FROM
cte
),
prox(FirstName,SecondName)
AS (SELECT
a.name,
b.name
FROM
cteGroup AS a
CROSS JOIN cteGroup AS b
WHERE
a.name < b.name
AND ABS(DATEDIFF(mi,a.dt,b.dt)) < 5
)
SELECT
FirstName,
SecondName,
COUNT(*)
FROM
prox
GROUP BY
FirstName,
SecondName
HAVING
COUNT(*) > 1
ORDER BY
1,
2