Grouping and counting rows by value until it changes

前端 未结 2 1585
心在旅途
心在旅途 2020-12-15 00:47

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

2条回答
  •  旧巷少年郎
    2020-12-15 01:13

    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.

提交回复
热议问题