如何为IN列表中每个分组获取前3条SQL查询结果?
解决每个dealerName与make组合取前3条数据的问题
这个需求用窗口函数就能轻松搞定,不用再死磕GROUP BY啦!核心思路是给每个dealerName+make的组合单独编号,然后筛选出每个分组里编号前3的行。
完整查询语句
WITH RankedCars AS ( SELECT a.make, a.model, a.colour, b.price, c.dealerCode, c.dealerName, -- 按dealerName和make分组,给每组内的行编号 ROW_NUMBER() OVER ( PARTITION BY c.dealerName, a.make ORDER BY b.price -- 这里可以根据你需要的排序规则调整,比如a.model或者其他字段 ) AS row_num FROM Dealers c INNER JOIN Cars a on a.make = c.make INNER JOIN Prices b on a.make = b.make WHERE c.dealerName IN ('A', 'B', 'C') AND a.make IN ('VW','FIAT','Volvo') AND b.price_range = 'X1' ) SELECT make, model, colour, price, dealerCode FROM RankedCars WHERE row_num <= 3; -- 只保留每个分组的前3条
关键部分解释
- CTE(RankedCars):先给所有符合条件的数据加上分组编号,用
ROW_NUMBER()窗口函数实现。PARTITION BY c.dealerName, a.make:指定按经销商名称和汽车品牌这两个字段分组,每个分组单独计算行号。ORDER BY b.price:你提到暂不要求排序规则,这里随便选了价格作为排序依据,要是有特定需求(比如按车型名称排序),直接改这个字段就行。
- 最终筛选:从CTE里选出编号≤3的行,这样每个
dealerName+make组合就只会返回前3条数据了。
为什么不用GROUP BY?
GROUP BY主要是用来做聚合计算(比如求和、计数)的,没法直接返回每个分组的前N条明细数据,而窗口函数就是专门处理这种“分组内排名/筛选”场景的工具,比GROUP BY更适合你的需求。
内容的提问来源于stack exchange,提问作者user3211098
相关产品推荐
相关产品推荐

