Reputation: 61
I have a SQL Server table that stores an event with datetime, like this:
ES TimeStamp
----------------------------
1 2018-03-05 00:00:12.000
1 2018-03-05 00:00:32.000
0 2018-03-05 00:00:52.000
0 2018-03-05 00:01:12.000
1 2018-03-05 00:01:32.000
1 2018-03-05 00:01:52.000
0 2018-03-05 00:02:12.000
0 2018-03-05 00:02:32.000
0 2018-03-05 00:02:52.000
0 2018-03-05 00:03:12.000
1 2018-03-05 00:03:32.000
1 2018-03-05 00:03:52.000
1 2018-03-05 00:04:12.000
I am looking for a fast way to select from my table:
ES StartTimeStamp EndTimeStamp
-------------------------------------------------------
1 2018-03-05 00:00:12.000 2018-03-05 00:00:32.000
0 2018-03-05 00:00:52.000 2018-03-05 00:01:12.000
1 2018-03-05 00:01:32.000 2018-03-05 00:01:52.000
0 2018-03-05 00:02:12.000 2018-03-05 00:03:12.000
1 2018-03-05 00:03:32.000 2018-03-05 00:04:12.000
Upvotes: 2
Views: 161
Reputation: 13393
You can use Gaps and Islands solution.
SELECT ES, MIN([TimeStamp]) StartTimeStamp, MAX([TimeStamp]) EndTimeStamp FROM
(SELECT *,
GRP = ROW_NUMBER() OVER(ORDER BY [TimeStamp]) -
ROW_NUMBER() OVER(PARTITION BY ES ORDER BY [TimeStamp]) FROM @MyTable) AS T
GROUP BY ES, GRP
Sample Data:
DECLARE @MyTable TABLE (ES INT ,[TimeStamp] DATETIME)
INSERT INTO @MyTable VALUES
(1, '2018-03-05 00:00:12.000'),
(1, '2018-03-05 00:00:32.000'),
(0, '2018-03-05 00:00:52.000'),
(0, '2018-03-05 00:01:12.000'),
(1, '2018-03-05 00:01:32.000'),
(1, '2018-03-05 00:01:52.000'),
(0, '2018-03-05 00:02:12.000'),
(0, '2018-03-05 00:02:32.000'),
(0, '2018-03-05 00:02:52.000'),
(0, '2018-03-05 00:03:12.000'),
(1, '2018-03-05 00:03:32.000'),
(1, '2018-03-05 00:03:52.000'),
(1, '2018-03-05 00:04:12.000')
Result:
ES StartTimeStamp EndTimeStamp
----------- ----------------------- -----------------------
1 2018-03-05 00:00:12.000 2018-03-05 00:00:32.000
0 2018-03-05 00:00:52.000 2018-03-05 00:01:12.000
1 2018-03-05 00:01:32.000 2018-03-05 00:01:52.000
0 2018-03-05 00:02:12.000 2018-03-05 00:03:12.000
1 2018-03-05 00:03:32.000 2018-03-05 00:04:12.000
Upvotes: 3
Reputation: 46219
You can use LAG
to make the group,then group by the subquery will get the expect.
SELECT t.ES ,
MIN(t.TimeStamp) AS 'StartTimeStamp' ,
MAX(t.TimeStamp) AS 'EndTimeStamp'
FROM ( SELECT * ,
MAX(flag) OVER ( ORDER BY t.TimeStamp ) rn
FROM ( SELECT * ,
CASE WHEN t.ES = LAG(t.ES) OVER ( ORDER BY TimeStamp )
THEN 0
ELSE t.id
END flag
FROM ( SELECT * ,
ROW_NUMBER() OVER ( ORDER BY TimeStamp ) AS id
FROM T
) AS t
) AS t
) AS t
GROUP BY t.es ,
t.rn
Upvotes: 1