SQL 分组(分区)排序获取第一条数据 ROW_NUMBER() OVER() PARTITION BY的使用

SQL查询:选取商品最高价格及最新设置记录
本文介绍了如何使用SQL的ROW_NUMBER() OVER()和PARTITION BY功能,结合ORDER BY子句,从‘订单价格设置’表中选取每个商品的最大价格和对应的价格设置时间id最大的记录。首先,通过ROW_NUMBER()函数对每个商品分区并按价格降序、设置时间id降序排序,然后筛选出每个分组的第一个记录,即为所求。这种方法在数据库查询中常用于获取每个分组的特定行,如最大值或最小值记录。

有一张价格 “订单价格设置” 表如下:

商品编号,价格设置时间id(类似于创建时间,创建时间约早,则act_id越小) ,价格的时间段,商品价格

现在要求选出每个商品价格最大,价格设置时间id最大的那条记录,要求先考虑价格,再考虑设置时间 

理想的结果:取出的是第3条记录 和第5条记录

思路:将数据根据item分区,再在每个分区中进行排序,先根据价格排序,再根据设置时间id排序,最后取出每个分组的第一条记录

实现:

利用 ROW_NUMBER() OVER(),PARTITION BY,ORDER BY

先直接上代码:

select item,act_id,loc_id,start_date,end_date,price, 
ROW_NUMBER() over( partition by item order by price desc,act_id desc) as new_index 
from test1

查询结果如下

可以看到查询出的结果已经进行了分区和进行了一次排序,并且增加了排序标记new_index

接下来只需从结果中查出new_index = 1的记录即为我们想要的结果:

select * from
(select item,act_id,loc_id,start_date,end_date,price, 
ROW_NUMBER() over( partition by item order by price desc,act_id desc) as new_index 
from test1)b where b.new_index = 1

结果如下:

ROW_NUMBER() OVER()和 PARTITION BY

① ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,可多个字段

在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)

② PARTITION BY 分区函数可以根据某字段分区并返回所有结果集,作为分区函数一般与Row_Number() over()排序一起连用,可实现分区排序的功能

它和聚合函数不同的地方在于它能够返回一个分组中的多条记录,而聚合函数一般只有一个反映统计值的记录。

`ROW_NUMBER() OVER (PARTITION BY)` 是 Oracle SQL 中的窗口函数,用于在每个分区内对每一行进行排序并编号,从 1 开始赋予连续的编号,常用于分析和报表等场景,帮助对数据进行分区排序获取排名信息。以下是几个使用示例: ### 对客户信息按客户编号分组并按修改日期降序排序 ```sql select row_number() over(partition by m.customerNo order by m.modifydate desc) rk, m.name, m.sex, m.idtype, m.idno, m.modifydate from customerInfo m; ``` 此示例中,`partition by m.customerNo` 按客户编号对 `customerInfo` 表中的数据进行分组,`order by m.modifydate desc` 在每个分组内按修改日期降序排序,`row_number()` 为每个分组内的行从 1 开始编号,编号结果存储在 `rk` 列中 [^3]。 ### 对订单信息按用户 ID 分组并按订单总价降序排序 ```sql select Id, UserId, orderTime, ROW_NUMBER() over(partition by UserId order by TotalPrice desc) as rowIndex from OrderInfo; ``` 这里 `partition by UserId` 按用户 ID 对 `OrderInfo` 表的数据分组,`order by TotalPrice desc` 在每个分组内按订单总价降序排序,`ROW_NUMBER()` 为每个分组内的行编号,编号存储在 `rowIndex` 列 [^4]。 ### 去除临时表中重复列 ```sql select t.*, row_number() over(partition by base_group_id order by base_task_agent_id) rid from cte t; ``` 该示例从临时表 `cte`(别名 `t`)中查询数据,`partition by base_group_id` 按 `base_group_id` 列分组,`order by base_task_agent_id` 在每个分组内按 `base_task_agent_id` 列排序,`row_number()` 为每个分组内的行编号,编号存储在 `rid` 列,可用于去除重复列 [^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值