SQL实现按用户分组,各商品类型取Top1记录
按用户+商品类型分组取最高记录的SQL实现
示例数据
| user_id | item_type | item_count |
|---|---|---|
| 11 | A | 10 |
| 11 | A | 9 |
| 11 | A | 2 |
| 11 | B | 4 |
| 11 | B | 1 |
| 11 | C | 2 |
| 12 | A | 2 |
| 12 | B | 4 |
| 12 | B | 1 |
| 12 | D | 1 |
期望输出
| user_id | item_type | item_count |
|---|---|---|
| 11 | A | 10 |
| 11 | B | 4 |
| 11 | C | 2 |
| 12 | A | 2 |
| 12 | B | 4 |
| 12 | D | 1 |
需求说明
需要为每个用户,取出其拥有的每种item_type中item_count最高的记录。比如用户11要获取item_type A、B、C各自的最高记录。
原SQL问题分析
你之前尝试的SQL仅能按用户取TopN记录,无法满足按用户+item_type分组取Top1的需求:
select * from ( select user_id, item_type, item_count, row_number() over (partition by user order by item_count desc) as item_rank from table) ranks where item_rank <= 2;
问题出在partition by user(此处应为user_id),它仅按用户分组排序,取的是用户所有商品中的TopN,而非每个类型下的Top1。
正确SQL实现
要实现按用户+item_type分组取最高记录,需将partition by的字段改为user_id, item_type,让每个用户的每个商品类型单独分组排序,再取排名为1的记录:
select user_id, item_type, item_count from ( select user_id, item_type, item_count, row_number() over (partition by user_id, item_type order by item_count desc) as item_rank from your_table_name -- 替换为实际表名 ) ranks where item_rank = 1;
补充说明
- 若同一用户同一类型下存在
item_count相同的记录,row_number()会随机选取其中一条。如果需要保留所有相同最高值的记录,可改用rank()或dense_rank():
select user_id, item_type, item_count from ( select user_id, item_type, item_count, rank() over (partition by user_id, item_type order by item_count desc) as item_rank from your_table_name ) ranks where item_rank = 1;
内容的提问来源于stack exchange,提问作者bockbock
相关产品推荐
相关产品推荐

