I have a table where messages are stored as they happen. Usually there is a message \'A\' and sometimes the A\'s are separated by a single message \'B\'. Now I want to group
Here is a little bit smaller solution:
DECLARE @t TABLE ( d DATE, m CHAR(1) )
INSERT INTO @t
VALUES ( '20150301', 'A' ),
( '20150302', 'A' ),
( '20150303', 'B' ),
( '20150304', 'A' ),
( '20150305', 'A' ),
( '20150306', 'A' ),
( '20150307', 'B' );
WITH
c1 AS(SELECT d, m, IIF(LAG(m, 1, m) OVER(ORDER BY d) = m, 0, 1) AS n FROM @t),
c2 AS(SELECT m, SUM(n) OVER(ORDER BY d) AS n FROM c1)
SELECT m, COUNT(*) AS c
FROM c2
GROUP BY m, n
Output:
m c
A 2
B 1
A 3
B 1
The idea is to get value 1 at rows where message is changed:
2015-03-01 A 0
2015-03-02 A 0
2015-03-03 B 1
2015-03-04 A 1
2015-03-05 A 0
2015-03-06 A 0
2015-03-07 B 1
The second step is just sum of current row value + all preceding values:
2015-03-01 A 0
2015-03-02 A 0
2015-03-03 B 1
2015-03-04 A 2
2015-03-05 A 2
2015-03-06 A 2
2015-03-07 B 3
This way you get grouping sets by message column and calculated column.