row_number() over partition by 分组聚合

本文详细介绍了如何使用SQL的ROW_NUMBER()函数对学生成绩进行排序,包括按课程分组并设置70分分界线。通过实例展示了如何结合partition by和case when语句实现特定条件下的成绩排列。

转自https://blog.youkuaiyun.com/yilulvxing/article/details/85098273

row_number 语法
ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号。在查询时应用了一个排序标准后,只有通过编号才能够保证其顺序是一致的,当使用ROW_NUMBER函数时,也需要专门一列用于预先排序以便于进行编号

partition by关键字是分析性函数的一部分,它和聚合函数不同的地方在于它能返回一个分组中的多条记录,而聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组,分区函数一般与排名函数一起使用。

原始表score:

s_id 表是学生编号,c_id表是课程编号,s_score 表是学生对应的课程分数
在这里插入图片描述

1.要求:得出每门课程的学生成绩排序(升序)

----因为是每门课程的结果,并且要排序,所以用row_number

select * ,row_number() over (partition by c_id order by s_score) from score;
返回结果:

在这里插入图片描述

2:进一步要求:得出每门课程的学生成绩,并且按照70分作为分割线排序—即低于70分的排序,高于70分的排序

select * ,row_number() over (partition by c_id,(case when s_score>70 then 1 else 0 end) order by s_score) from score;

返回结果:

在这里插入图片描述

 

`ROW_NUMBER()` 是 SQL 中的窗口函数(Window Function),用于为每一行分配一个唯一的行号。当与 `OVER(PARTITION BY ... ORDER BY ...)` 结合使用时,可以在分组数据中为每一行生成一个序号,这在处理需要分组排序的场景中非常有用。 ### 作用 - **分组排序**:`PARTITION BY` 子句用于定义分组,类似于 `GROUP BY`,但不会将数据聚合,而是保留每一行的数据。在每个分组内部,`ORDER BY` 子句用于指定排序规则,从而为每一行分配一个行号。 - **生成唯一序号**:在每个分组内,`ROW_NUMBER()` 会根据指定的排序规则为每一行生成一个唯一的序号。即使有重复值,行号也不会重复。 例如,在引用中提到的查询: ```sql SELECT ROW_NUMBER() OVER(PARTITION BY DocEntry ORDER BY Quantity DESC) AS ID, DocEntry AS '订单号', LineNum+1 AS 行号, Quantity AS 数量 FROM [POR1] WHERE DocEntry IN (97,133) ``` 该查询的作用是为 `DocEntry` 相同的记录分组,并在每个分组内按照 `Quantity` 降序排列,为每一行分配一个唯一的 `ID` 值[^1]。 ### 类型 `ROW_NUMBER()` 是窗口函数的一种,属于 **排序函数**。它通常与以下几种子句一起使用: - `OVER()`:定义窗口函数的范围。 - `PARTITION BY`:指定分组列,类似于 `GROUP BY`,但不会聚合数据。 - `ORDER BY`:在每个分组内定义排序规则。 窗口函数的常见类型包括: - **排序函数**:如 `ROW_NUMBER()`、`RANK()`、`DENSE_RANK()`,用于生成排名或序号。 - **聚合函数**:如 `SUM()`、`AVG()`、`MIN()`、`MAX()`,用于在窗口范围内进行计算。 - **分布函数**:如 `PERCENT_RANK()`、`CUME_DIST()`,用于计算行在窗口中的分布位置。 ### 使用场景 1. **去重**:通过 `ROW_NUMBER()` 为每组数据分配序号,然后筛选出每组的第一条数据,从而实现去重[^2]。例如: ```sql SELECT * FROM ( SELECT name, ROW_NUMBER() OVER(PARTITION BY name ORDER BY timestamp DESC) AS idx, value, timestamp FROM duplicate_test WHERE is_delete = 0 ) t WHERE idx = 1
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值