如何根据 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]
变化.
我正在尝试获取像下面的 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]
变化.