That was interesting :)
;WITH cte as (
SELECT Messages.Message, Timestamp,
ROW_NUMBER() OVER(PARTITION BY Message ORDER BY Timestamp) AS gn,
ROW_NUMBER() OVER (ORDER BY Timestamp) AS rn
FROM Messages
), cte2 AS (
SELECT Message, Timestamp, gn, rn, gn - rn as gb
FROM cte
), cte3 AS (
SELECT Message, MIN(Timestamp) As Ts, COUNT(1) as Cnt
FROM cte2
GROUP BY Message, gb)
SELECT Message, Cnt FROM cte3
ORDER BY Ts
Here is the result set:
Message Cnt
A 2
B 1
A 3
B 1
The query may be shorter but I post it that way so you can see what's happening.
The result is exactly as requested. This is the most important part gn - rn
the idea is to number the rows in each partition and at the same time number the rows in the whole set then if you subtract the one from the other you'll get the 'rank' of each group.
;WITH cte as (
SELECT Messages.Message, Timestamp,
ROW_NUMBER() OVER(PARTITION BY Message ORDER BY Timestamp) AS gn,
ROW_NUMBER() OVER (ORDER BY Timestamp) AS rn
FROM Messages
), cte2 AS (
SELECT Message, Timestamp, gn, rn, gn - rn as gb
FROM cte
)
SELECT * FROM cte2
Message Timestamp gn rn gb
A 2015-03-29 00:00:00.000 1 1 0
A 2015-03-29 00:01:00.000 2 2 0
B 2015-03-29 00:02:00.000 1 3 -2
A 2015-03-29 00:03:00.000 3 4 -1
A 2015-03-29 00:04:00.000 4 5 -1
A 2015-03-29 00:05:00.000 5 6 -1
B 2015-03-29 00:06:00.000 2 7 -5
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…