SQL服务器Window函数根据前后行是否属于同一类型按顺序分配组

SQL Server Window Function assign groups by order based on whether or not the row before or after is of the same type

有没有办法在SQL服务器中使用window函数按列排序,然后根据前后行是否属于同一类型来分配组?

假设 table [tbl1]

SELECT * FROM tbl1 ORDER BY SEQ

生成此输出。

SEQ  Type
1    a
2    a
3    b
4    a
5    c
6    c

你能用 window 函数产生这个结果吗?

SEQ  Type  Group
1    a     1
2    a     1
3    b     2
4    a     3
5    c     4
6    c     4

请注意,第 4 行被视为一个单独的组,因为第 3 行或第 5 行不是类型 'a'。

您可以使用不同的行号来做到这一点。这是一种产生序列号的方法

select seq, type,
       dense_rank() over (order by grp, type)
from (select t.*, 
             (row_number() over (order by seq) -
              row_number() over (partition by type order by seq)
             ) as grp
      from tbl1 t
     ) t;

请注意,这允许 seq 中存在间隙。如果没有间隙,您可以将第一个 row_number() 替换为 seq.

这是基于 LAGSUM 的不同解决方案,具有 OVER (ORDER BY ...) window 功能,可从 SQL Server 2012 起获得:

SELECT SEQ, Type, SUM(flag) OVER(ORDER BY SEQ) + 1 AS [Group]
FROM (
   SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
                  ELSE 0
             END AS flag                   
   FROM #tbl1 ) t

这个子查询:

SELECT *, CASE WHEN LAG(Type) OVER(ORDER BY SEQ) <> Type THEN 1
               ELSE 0
          END AS flag                  
FROM #tbl1

产生此输出(基于 OP 的示例数据):

SEQ Type flag
----------------
1   a    0
2   a    0
3   b    1
4   a    1
5   c    1
6   c    0

flag 表示 Type 的变化。外部查询将组数计算为 运行 总数 of flag.

输出:

SEQ Type Group
--------------
1   a    1
2   a    1
3   b    2
4   a    3
5   c    4
6   c    4