分组Top N 问题

今天面试,面试官给了这样一个场景:
有两张表,一张表存放 车队ID,班组ID,司机ID
另一种表存放 司机ID,运营时间,运营里程

要查询出 7月份每个车队每个班组里的 Top 3

这就要用到 ROW_NUMBER() 函数

首先按需求建两张表

CREATE TABLE demo_of_topn_car
(
companyid varchar(8),
classid varchar(8),
driverid varchar(8)
)

CREATE TABLE demo_of_topn_operating
(
driverid varchar(8),
operadate datetime,
mileage DECIMAL(5,2)
)

第一步思路 先把每个车队每个班组每个司机的运营总和计算出来

SELECT car.companyid,car.classid,operat.driverid,sum(mileage) mileage from
(
SELECT companyid,classid FROM demo_of_topn_car GROUP BY companyid,classid
) car
LEFT JOIN
(
SELECT a.companyid,a.classid,a.driverid,b.mileage 
FROM demo_of_topn_car a
LEFT JOIN demo_of_topn_operating b on a.driverid = b.driverid
) operat ON car.companyid = operat.companyid AND car.classid = operat.classid
GROUP BY car.companyid,car.classid,operat.driverid

然后对结果集进行分组排序

SELECT companyid,classid,driverid,row_number() over (PARTITION by companyid,classid ORDER BY mileage desc) rid from (
SELECT car.companyid,car.classid,operat.driverid,sum(mileage) mileage from
(
SELECT companyid,classid FROM demo_of_topn_car GROUP BY companyid,classid
) car
LEFT JOIN
(
SELECT a.companyid,a.classid,a.driverid,b.mileage 
FROM demo_of_topn_car a
LEFT JOIN demo_of_topn_operating b on a.driverid = b.driverid
) operat ON car.companyid = operat.companyid AND car.classid = operat.classid
GROUP BY car.companyid,car.classid,operat.driverid
ORDER BY mileage DESC
) t1 

切记:求 Top N 都是倒序

最后需要在外面嵌套一层,或者用with

with res as (
SELECT companyid,classid,driverid,row_number() over (PARTITION by companyid,classid ORDER BY mileage desc) rid from (
SELECT car.companyid,car.classid,operat.driverid,sum(mileage) mileage from
(
SELECT companyid,classid FROM demo_of_topn_car GROUP BY companyid,classid
) car
LEFT JOIN
(
SELECT a.companyid,a.classid,a.driverid,b.mileage 
FROM demo_of_topn_car a
LEFT JOIN demo_of_topn_operating b on a.driverid = b.driverid
) operat ON car.companyid = operat.companyid AND car.classid = operat.classid
GROUP BY car.companyid,car.classid,operat.driverid
ORDER BY mileage DESC
) t1 )  

SELECT * from res where rid <= 3

不知道大家有什么更好的办法,欢迎指导。 :)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值