您可以使用CROSS APPLY 来初始选择事件2-6:
SELECT t1.Id, t1.EventType, t1.Created AS StartTime, t3.EndTime
FROM mytable AS t1
CROSS APPLY (
SELECT TOP 1 t2.Id, t2.Created
FROM mytable AS t2
WHERE t1.EventType = t2.EventType AND
t2.Id <> t1.Id AND
ABS(DATEDIFF(ss, t1.Created, t2.Created)) <= 60
ORDER BY DATEDIFF(ss, t1.Created, t2.Created) DESC) AS t3(Id, EndTime)
输出:
Id EventType StartTime EndTime
2 1 2015-11-16 15:12:17.000 2015-11-16 15:13:16.000
3 1 2015-11-16 15:12:18.000 2015-11-16 15:13:16.000
4 1 2015-11-16 15:12:19.000 2015-11-16 15:13:16.000
5 1 2015-11-16 15:12:20.000 2015-11-16 15:13:16.000
6 1 2015-11-16 15:13:16.000 2015-11-16 15:12:20.000
您现在可以检查记录桶是否包含 5 行或更多行,并使用 GROUP BY 获取第一条/最后一条记录:
SELECT MIN(t1.Id) AS StartID,
MAX(t3.Id) AS EndID,
t1.EventType,
MIN(t1.Created) AS StartTime, MAX(t3.EndTime) AS EndTime
FROM mytable AS t1
CROSS APPLY (
SELECT TOP 1 t2.Id, t2.Created
FROM mytable AS t2
WHERE t1.EventType = t2.EventType AND
t2.Id <> t1.Id AND
ABS(DATEDIFF(ss, t1.Created, t2.Created)) <= 120
ORDER BY DATEDIFF(ss, t1.Created, t2.Created) DESC) AS t3(Id, EndTime)
GROUP BY t1.EventType
HAVING COUNT(*) >= 5
输出:
StartID EndID EventType StartTime EndTime
2 6 1 2015-11-16 15:12:17.000 2015-11-16 15:13:16.000
编辑:
另一种方法是使用Recursive CTE:
;WITH CTE_RN AS (
SELECT Id, EventType, Created,
ROW_NUMBER() OVER (ORDER BY Created) AS rn
FROM mytable
), CTE_Buckets AS (
-- Anchor member: Get first row from table
SELECT Id, EventType, Created, CAST(1 AS BIGINT) AS row_num,
1 AS bucket_num, 0 AS time_diff
FROM CTE_RN
WHERE rn = 1
UNION ALL
-- Recursive member: Get next row. Reset time diff cumulative counter
-- if time difference exceeds two minutes
SELECT c1.Id, c1.EventType, c1.Created, c1.rn AS row_num,
-- All consecutive rows within the 2 minute time range fall within the same bucket
bucket_num = CASE
WHEN x.diff + time_diff > 120 THEN c2.bucket_num + 1
ELSE c2.bucket_num
END,
-- Calculate cummulative time diff.
time_diff = CASE
WHEN x.diff + time_diff > 120 THEN 0
ELSE x.diff + time_diff
END
FROM CTE_RN AS c1
INNER JOIN CTE_Buckets AS c2 ON c1.rn = c2.row_num + 1
CROSS APPLY (SELECT DATEDIFF(ss, c2.Created, c1.Created)) AS x(diff)
)
SELECT MIN(Id) AS StartID, MAX(Id) AS EndID,
MIN(Created) AS StartTime, MAX(Created) AS EndTime
FROM CTE_Buckets
GROUP BY bucket_num
HAVING COUNT(*) >= 5
此查询处理多个间隔组。