如何用ORDER BY表达式或窗口函数按Provider出现次数排序查询结果?
实现按Provider条目数量降序排序的优化方案
你的需求是把条目数最多的Provider排在结果最前面,原来用FIND_IN_SET的方法虽然能实现,但存在效率低、长度限制的问题,下面给你两种更可靠的实现方式:
方法一:窗口函数(MySQL 8.0+ 推荐)
用窗口函数COUNT() OVER (PARTITION BY provider)可以直接计算每个Provider对应的条目总数,然后按这个总数降序排序即可,逻辑清晰且效率更高:
select * from combined where valid_rating is null order by -- 按Provider的条目数降序,条目多的排前面 COUNT(*) OVER (PARTITION BY provider) desc, -- 可选:如果两个Provider条目数相同,可按Provider名称排序保证结果稳定 provider asc;
说明:
COUNT(*) OVER (PARTITION BY provider)会为每一行计算其所属Provider的总条目数,不需要额外关联子查询- 先按统计数降序,就能保证条目最多的Provider所有行都排在最前面;若多个Provider条目数相同,可追加排序字段(如
provider asc)确保结果一致性
方法二:子查询关联(兼容MySQL 5.x版本)
如果你的MySQL版本不支持窗口函数,可以先统计每个Provider的条目数,再和主查询关联后排序:
select c.* from combined c join ( select provider, count(*) as cnt from combined where valid_rating is null group by provider ) p on c.provider = p.provider where c.valid_rating is null order by p.cnt desc, c.provider asc;
说明:
- 子查询
p统计了每个符合条件的Provider的条目数cnt - 主查询通过
provider关联该子查询,再按cnt降序排序,同样能实现需求
原方法的问题
你原来用FIND_IN_SET的方式存在两个明显缺陷:
- 长度限制:MySQL中
FIND_IN_SET的第二个参数字符串长度受max_allowed_packet限制,如果Provider数量多、名称长,会导致字符串被截断,排序逻辑出错 - 效率低下:需要先生成有序的Provider字符串,再逐行匹配索引,性能远不如窗口函数或关联子查询的方式
内容的提问来源于stack exchange,提问作者David542
相关产品推荐
相关产品推荐

