Oracle中能否实现多层Partition By?如何生成指定Priority列
解决Oracle SQL生成Priority列的问题
问题分析
你的需求是给同一学生的不同Group生成Priority:按Rank降序排列,同一Rank下不同Group分配从2开始的递增数值。你之前的写法1+dense_rank() over (partition by Name, Group order by Rank desc)错误在于分区范围错误——把Name和Group一起作为分区键,每个分区里只有当前学生的单个Group数据,所以dense_rank()永远返回1,加1后全是2。
正确实现
你需要调整窗口函数的分区和排序逻辑:
- 按
Name和Rank分区,确保同一学生、同一Rank的所有Group被放在同一个窗口里 - 在该窗口内按
Group排序,用dense_rank()生成组内的递增序号,最后加1让起始值变成2
对应的SQL语句如下:
SELECT Name, "Group", Rank, dense_rank() OVER (PARTITION BY Name, Rank ORDER BY "Group") + 1 AS Priority FROM STUDENT ORDER BY Name, Rank DESC, "Group";
示例验证
假设STUDENT表数据如下:
| Name | Group | Rank |
|---|---|---|
| Jill | A | 3 |
| Jill | B | 3 |
| Jill | C | 2 |
| Jill | A | 2 |
| Jack | X | 4 |
执行上述SQL后得到的结果:
| Name | Group | Rank | Priority |
|---|---|---|---|
| Jack | X | 4 | 2 |
| Jill | A | 3 | 2 |
| Jill | B | 3 | 3 |
| Jill | A | 2 | 2 |
| Jill | C | 2 | 3 |
完全符合需求:同一学生按Rank降序,同Rank下不同Group的Priority从2开始递增。
补充说明
- 如果你的
Group列需要按特定规则排序(比如不是默认的字典序),直接在ORDER BY "Group"里替换成对应的排序逻辑即可 - 如果同Rank下存在重复的Group(同一学生同Rank同Group有多行),
dense_rank()会给相同的Group分配相同的Priority;如果需要每个行都递增,改用row_number()代替dense_rank()即可
内容的提问来源于stack exchange,提问作者Dev Solanki
相关产品推荐
相关产品推荐

