I have a table where it holds some vehicle events, I need to count the number of event occurrences every 5 minutes.
Sample :
CREATE TABLE Sample ( Id INT PRIMARY KEY NOT NULL, EventTime DATETIME NOT NULL, AssetId BIGINT NOT NULL, EventTypeId BIGINT NOT NULL, SeverityId INT NOT NULL ) INSERT INTO Sample VALUES (1,'2022-04-03 14:00:35',1166146709699346432,7222537533950015177,1), (2,'2022-04-03 14:06:37',1166146709699346432,7222537533950015177,1), (3,'2022-04-03 14:08:50',1166146709699346432,7222537533950015177,1), (4,'2022-04-03 14:09:48',1166146709699346432,7222537533950015177,1), (5,'2022-04-03 14:22:35',1166146709699346432,7222537533950015177,1), (6,'2022-04-03 14:22:55',1166146709699346432,7222537533950015177,1), (7,'2022-04-03 14:23:21',1166146709699346432,7222537533950015177,1), (8,'2022-04-03 14:25:02',1166146709699346432,7222537533950015177,1), (9,'2022-04-03 14:26:36',1166146709699346432,7222537533950015177,1), (10,'2022-04-03 15:07:55',1166146709699346432,7222537533950015177,1), (11,'2022-04-03 15:13:13',1166146709699346432,7222537533950015177,1), (12,'2022-04-03 15:14:28',1166146709699346432,7222537533950015177,1), (13,'2022-04-03 17:15:15',1166146709699346432,7222537533950015177,1), (14,'2022-04-03 17:19:47',1166146709699346432,7222537533950015177,1), (15,'2022-04-03 17:21:57',1166146709699346432,7222537533950015177,1), (16,'2022-04-03 18:09:02',1166146709699346432,7222537533950015177,1), (17,'2022-04-03 18:23:07',1166146709699346432,7222537533950015177,1), (18,'2022-04-03 18:27:05',1166146709699346432,7222537533950015177,1), (19,'2022-04-03 18:45:24',1166146709699346432,7222537533950015177,1), (20,'2022-04-03 18:45:55',1166146709699346432,7222537533950015177,1), (21,'2022-04-03 19:09:40',1166146709699346432,7222537533950015177,1), (22,'2022-04-03 19:10:31',1166146709699346432,7222537533950015177,1), (23,'2022-04-03 19:25:03',1166146709699346432,7222537533950015177,1), (24,'2022-04-03 19:32:05',1166146709699346432,7222537533950015177,1), (25,'2022-04-03 19:44:47',1166146709699346432,7222537533950015177,1), (26,'2022-04-03 19:46:43',1166146709699346432,7222537533950015177,1), (27,'2022-04-03 19:49:44',1166146709699346432,7222537533950015177,1), (28,'2022-04-03 19:50:59',1166146709699346432,7222537533950015177,1), (29,'2022-04-03 19:54:10',1166146709699346432,7222537533950015177,1), (30,'2022-04-03 20:00:36',1166146709699346432,7222537533950015177,1), (31,'2022-04-03 20:02:37',1166146709699346432,7222537533950015177,1), (32,'2022-04-03 20:02:46',1166146709699346432,7222537533950015177,1), (33,'2022-04-03 20:02:54',1166146709699346432,7222537533950015177,1), (34,'2022-04-03 20:15:03',1166146709699346432,7222537533950015177,1), (35,'2022-04-03 20:17:01',1166146709699346432,7222537533950015177,1), (36,'2022-04-03 20:17:12',1166146709699346432,7222537533950015177,1)
I was able to get the results by the following query :
SELECT * FROM ( SELECT Id , EventTime , DATEADD(MINUTE, 5, e1.EventTime) EndOfPeriod , AssetId , EventTypeId , SeverityId , ( SELECT COUNT(*) CNT FROM Sample e2 WHERE e2.EventTime >= e1.EventTime AND e2.EventTime <= DATEADD(MINUTE, 5, e1.EventTime) AND e2.EventTypeId = e1.EventTypeId AND e2.AssetId = e1.AssetId AND e2.SeverityId = e1.SeverityId ) TotalEvents , CASE WHEN e1.EventTime <= MAX(DATEADD(MINUTE, 5, e1.EventTime)) OVER(ORDER BY e1.EventTime, DATEADD(MINUTE, 5, e1.EventTime) ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) THEN 0 ELSE 1 END AS IsIncluded FROM Sample e1 ) e WHERE IsIncluded = 1
query results :
| Id | EventTime | EndOfPeriod | AssetId | EventTypeId | SeverityId | TotalEvents | IsIncluded | |----|----------------------|----------------------|---------------------|---------------------|------------|-------------|------------| | 1 | 2022-04-03T14:00:35Z | 2022-04-03T14:05:35Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 2 | 2022-04-03T14:06:37Z | 2022-04-03T14:11:37Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 | | 5 | 2022-04-03T14:22:35Z | 2022-04-03T14:27:35Z | 1166146709699346400 | 7222537533950015000 | 1 | 5 | 1 | | 10 | 2022-04-03T15:07:55Z | 2022-04-03T15:12:55Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 11 | 2022-04-03T15:13:13Z | 2022-04-03T15:18:13Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 13 | 2022-04-03T17:15:15Z | 2022-04-03T17:20:15Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 16 | 2022-04-03T18:09:02Z | 2022-04-03T18:14:02Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 17 | 2022-04-03T18:23:07Z | 2022-04-03T18:28:07Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 19 | 2022-04-03T18:45:24Z | 2022-04-03T18:50:24Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 21 | 2022-04-03T19:09:40Z | 2022-04-03T19:14:40Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 23 | 2022-04-03T19:25:03Z | 2022-04-03T19:30:03Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 24 | 2022-04-03T19:32:05Z | 2022-04-03T19:37:05Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 25 | 2022-04-03T19:44:47Z | 2022-04-03T19:49:47Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 | | 30 | 2022-04-03T20:00:36Z | 2022-04-03T20:05:36Z | 1166146709699346400 | 7222537533950015000 | 1 | 4 | 1 | | 34 | 2022-04-03T20:15:03Z | 2022-04-03T20:20:03Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 |
The issue with the above results is that the query excluded Ids (15 and 28) the correct output should be :
| Id | EventTime | EndOfPeriod | AssetId | EventTypeId | SeverityId | TotalEvents | IsIncluded | |----|----------------------|----------------------|---------------------|---------------------|------------|-------------|------------| | 1 | 2022-04-03T14:00:35Z | 2022-04-03T14:05:35Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 2 | 2022-04-03T14:06:37Z | 2022-04-03T14:11:37Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 | | 5 | 2022-04-03T14:22:35Z | 2022-04-03T14:27:35Z | 1166146709699346400 | 7222537533950015000 | 1 | 5 | 1 | | 10 | 2022-04-03T15:07:55Z | 2022-04-03T15:12:55Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 11 | 2022-04-03T15:13:13Z | 2022-04-03T15:18:13Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 13 | 2022-04-03T17:15:15Z | 2022-04-03T17:20:15Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 15 | 2022-04-03T17:21:57Z | 2022-04-03T17:26:57Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 16 | 2022-04-03T18:09:02Z | 2022-04-03T18:14:02Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 17 | 2022-04-03T18:23:07Z | 2022-04-03T18:28:07Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 19 | 2022-04-03T18:45:24Z | 2022-04-03T18:50:24Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 21 | 2022-04-03T19:09:40Z | 2022-04-03T19:14:40Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 23 | 2022-04-03T19:25:03Z | 2022-04-03T19:30:03Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 24 | 2022-04-03T19:32:05Z | 2022-04-03T19:37:05Z | 1166146709699346400 | 7222537533950015000 | 1 | 1 | 1 | | 25 | 2022-04-03T19:44:47Z | 2022-04-03T19:49:47Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 | | 28 | 2022-04-03T19:50:59Z | 2022-04-03T19:55:59Z | 1166146709699346400 | 7222537533950015000 | 1 | 2 | 1 | | 30 | 2022-04-03T20:00:36Z | 2022-04-03T20:05:36Z | 1166146709699346400 | 7222537533950015000 | 1 | 4 | 1 | | 34 | 2022-04-03T20:15:03Z | 2022-04-03T20:20:03Z | 1166146709699346400 | 7222537533950015000 | 1 | 3 | 1 |
your help would be much appreciated.
Advertisement
Answer
I believe this can only be done via recursive cte because the 5 minute window can contain arbitrary number of rows… a situation where lead/lag/rows between x preceding will not work. Here is my stab at it:
with ncte as ( select *, rn = row_number() over (partition by AssetId, EventTypeId, SeverityId order by EventTime) from sample ), rcte as ( select Id, EventTime, AssetId, EventTypeId, SeverityId, rn, EventTime as BaseTime from ncte where rn = 1 union all select curr.Id, curr.EventTime, curr.AssetId, curr.EventTypeId, curr.SeverityId, curr.rn, case when curr.EventTime < dateadd(minute, 5, prev.BaseTime) then prev.BaseTime else curr.EventTime end from ncte as curr join rcte as prev on curr.rn = prev.rn + 1 and curr.AssetId = prev.AssetId and curr.EventTypeId = prev.EventTypeId and curr.SeverityId = prev.SeverityId ) select min(case when EventTime = BaseTime then Id end), AssetId, EventTypeId, SeverityId, BaseTime, count(*) as TotalEvents from rcte group by AssetId, EventTypeId, SeverityId, BaseTime