如何根据 sql 查询结果中的顺序枚举一组连续的行

How to enumerate a continuous group of rows based on order in result of sql query

我正在尝试获取像下面的 desired_output 列这样的列,并尝试了像 DENSE_RANK 和 ROW_NUMBER 这样的函数,但是似乎无法在这里获得正确的组合。我没有密钥来识别 连续组 之间的 "transition"。

因此,每次它在每个 id_key 击中一个新组时,无论它之前是否已经击中过该组(按顺序排序)我想开始一个新的 "transition"

最终目标是根据 desired_output 得到像 MIN 和 MAX sequence 这样的东西,我正打算这样做用 GROUP BY 做。我能够使用 LEAD/LAG/JOINS 的复杂查询来完成此操作,但想看看是否有人知道类似 DENSE_RANK 的函数(或使用 DENSE_RANK 的方法)会给出 desired_output 下面(画全图)。

谢谢!

id_key      sequence    group       desired_output          
1           1           A           1
1           2           A           1
1           3           B           2
1           4           B           2
1           5           B           2
1           6           B           2
1           7           C           3
1           8           C           3
1           9           C           3
1           10          B           4
1           11          B           4
1           12          B           4
1           13          C           5
1           14          C           5
2           15          A           1
2           16          A           1
2           17          B           2
2           18          B           2
2           19          C           3
2           20          C           3
2           21          B           4
2           22          C           5
2           23          C           5
2           24          C           5
我猜

SQL Dense_Rank() function 是解决这个要求的正确方法。 您可能错过了可以在 window 函数中使用的 Partition By 子句。

这是一个 Select 可能有帮助的查询

--create table myrows (id_key int, [sequence] int, [group] varchar(3))
/*
insert into myrows select   1   ,   1   ,'A'    
insert into myrows select   1   ,   2   ,'A'    
insert into myrows select   1   ,   3   ,'B'    
insert into myrows select   1   ,   4   ,'B'    
insert into myrows select   1   ,   5   ,'B'    
insert into myrows select   1   ,   6   ,'B'    
insert into myrows select   1   ,   7   ,'C'    
insert into myrows select   1   ,   8   ,'C'    
insert into myrows select   1   ,   9   ,'C'    
insert into myrows select   1   ,   10  ,'B'    
insert into myrows select   1   ,   11  ,'B'    
insert into myrows select   1   ,   12  ,'B'    
insert into myrows select   1   ,   13  ,'C'    
insert into myrows select   1   ,   14  ,'C'    
insert into myrows select   2   ,   15  ,'A'    
insert into myrows select   2   ,   16  ,'A'    
insert into myrows select   2   ,   17  ,'B'    
insert into myrows select   2   ,   18  ,'B'    
insert into myrows select   2   ,   19  ,'C'    
insert into myrows select   2   ,   20  ,'C'    
insert into myrows select   2   ,   21  ,'B'    
insert into myrows select   2   ,   22  ,'C'    
insert into myrows select   2   ,   23  ,'C'    
insert into myrows select   2   ,   24  ,'C'    
*/

select *, 
    DENSE_RANK() over (partition by id_key order by [group]) desired_output
from myrows

试试这个:

SELECT id_key, sequence, [group],
       SUM(flag) OVER (PARTITION BY id_key 
                       ORDER BY sequence) + 1 AS desired_output
FROM (
  SELECT id_key, sequence, [group],
         IIF(LAG([group]) OVER (PARTITION BY id_key 
                                ORDER BY sequence) <> [group], 1, 0) AS flag
  FROM mytable) AS t
ORDER BY sequence

flag 字段标记每个 id_key 分区内 [group] 列中的任何更改。外部查询使用 flag 字段来计算 运行 总数 ,以便考虑每个 id_key 分区中的所有 [group] 变化.