基于现有序列的SQL二次排名问题:DENSE_RANK结果无序求助
解决连续Event分组的二次排名问题
看起来你是想给**连续出现的相同Event(包括空值情况)**分配递增的排名——也就是把连续的相同Event视为一个独立组,每个组对应唯一的排名对吧?你之前用的DENSE_RANK()写法没办法识别这种连续组,因为它只会根据Event的静态值来排名,不管这些Event是不是连续出现的。
先明确我们的目标排名效果
根据你的数据集,理想的二次排名应该是这样的:
| ID | Sequence | Event | secondary_rank |
|---|---|---|---|
| xxx | 1 | 1 | |
| xxx | 2 | B | 2 |
| xxx | 3 | B | 2 |
| xxx | 4 | B | 2 |
| xxx | 5 | B | 2 |
| xxx | 6 | A | 3 |
| xxx | 7 | 4 | |
| xxx | 8 | C | 5 |
| xxx | 9 | C | 5 |
| xxx | 10 | C | 5 |
| xxx | 11 | C | 5 |
| xxx | 12 | C | 5 |
解决方案:用「孤岛和间隙」技巧实现连续分组
我们需要先识别出连续的Event组,再给每个组分配排名,具体步骤如下:
1. 完整SQL代码
SELECT ID, Sequence, Event, DENSE_RANK() OVER (PARTITION BY ID ORDER BY group_identifier) AS secondary_rank FROM ( SELECT ID, Sequence, Event, -- 计算组标识:全局行号 - 同Event分组内的行号,连续相同Event会得到相同值 ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Sequence) - ROW_NUMBER() OVER (PARTITION BY ID, COALESCE(Event, 'NO_EVENT') ORDER BY Sequence) AS group_identifier FROM your_table ) ranked_groups ORDER BY Sequence;
2. 代码逻辑拆解
- 处理空Event:用
COALESCE(Event, 'NO_EVENT')把空值替换成固定标识,避免NULL在分组时的异常。 - 生成组标识:
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Sequence):按Sequence生成全局递增的行号。ROW_NUMBER() OVER (PARTITION BY ID, COALESCE(Event, 'NO_EVENT') ORDER BY Sequence):按ID和处理后的Event分组,生成组内的行号。- 两者的差值就是连续Event组的唯一标识——同一连续组的差值固定,不同组的差值不同。
- 生成二次排名:对组标识用
DENSE_RANK()排序,就能得到每个连续组的递增排名。
为什么你之前的写法不对?
你原来的代码:
DENSE_RANK() OVER (Partition BY ID ORDER BY ID, Event)
因为ID是同一个值,实际排序逻辑是按Event值来的。所有空Event会被归为同一类,所以DENSE_RANK会给Sequence1和7的空Event都分配排名1,无法区分它们是不连续的两个独立组,这就是你觉得排名无序的原因。
内容的提问来源于stack exchange,提问作者emustyle
相关产品推荐
相关产品推荐

