上一篇
场景引入:
小张最近接手了一个电商数据分析需求,老板要求他"统计每个品类下销售额Top 3的商品",当他用GROUP BY
搞定基础分组后,突然卡壳了——怎么优雅地实现排名呢?🤔 别急!今天我们就来解锁MySQL三大排名函数,让你像切蛋糕一样轻松处理排名问题!
ROW_NUMBER()
:最耿直的编号特点:纯序号分配,相同值也强制区分排名
SELECT product_name, sales, ROW_NUMBER() OVER(ORDER BY sales DESC) AS '排名' FROM products;
输出效果:
+-------------+-------+------+
| product_name| sales | 排名 |
+-------------+-------+------+
| 手机Pro | 5000 | 1 |
| 智能手表 | 3000 | 2 | ← 即使下条记录相同
| 无线耳机 | 3000 | 3 | ← 依然强制编号
| 充电宝 | 1000 | 4 |
+-------------+-------+------+
RANK()
:学霸排名法 👑特点:并列占用名次,后续排名跳跃(像考试排名)
SELECT student_name, score, RANK() OVER(ORDER BY score DESC) AS '排名' FROM exam_results;
输出效果:
+-------------+-------+------+
| student_name| score | 排名 |
+-------------+-------+------+
| 张三 | 99 | 1 |
| 李四 | 95 | 2 |
| 王五 | 95 | 2 | ← 并列第二
| 赵六 | 90 | 4 | ← 直接跳到第四
+-------------+-------+------+
DENSE_RANK()
:温柔连续排名 🌈特点:并列不跳号,适合"前N名"场景
SELECT employee_name, salary, DENSE_RANK() OVER(ORDER BY salary DESC) AS '薪资排名' FROM staff;
输出效果:
+-------------+--------+----------+
| employee_name| salary | 薪资排名 |
+-------------+--------+----------+
| 马云 | 50000 | 1 |
| 马化腾 | 48000 | 2 |
| 刘强东 | 48000 | 2 | ← 并列第二
| 雷军 | 45000 | 3 | ← 依然连续
+-------------+--------+----------+
场景:统计每个部门薪资排名(分组内排名)
SELECT department, employee_name, salary, DENSE_RANK() OVER( PARTITION BY department -- 按部门分区 ORDER BY salary DESC ) AS '部门内排名' FROM company_data;
输出效果:
+------------+-------------+--------+--------------+
| department | employee_name| salary | 部门内排名 |
+------------+-------------+--------+--------------+
| 技术部 | 程序员A | 20000 | 1 |
| 技术部 | 程序员B | 18000 | 2 |
| 市场部 | 销售冠军 | 25000 | 1 | ← 不同部门重新排名
| 市场部 | 销售新人 | 15000 | 2 |
+------------+-------------+--------+--------------+
需求:找出每个品类销量前三的商品
WITH ranked_products AS ( SELECT category, product_name, sales, ROW_NUMBER() OVER( PARTITION BY category ORDER BY sales DESC ) AS rank_in_category FROM products ) SELECT * FROM ranked_products WHERE rank_in_category <= 3; -- 只要前三名
技巧:
ROW_NUMBER
/RANK
/DENSE_RANK
版本确认:
MySQL 8.0+ 才支持窗口函数(2025年主流云服务已默认支持)
性能优化:
-- 为排序字段加索引能大幅提升性能 CREATE INDEX idx_sales ON products(sales DESC);
NULL值处理:
NULLS FIRST/LAST
调整(MySQL 8.0+支持) 特殊场景解决方案:
RANK
会出现跳号,用DENSE_RANK
则不会 LIMIT
,避免直接在窗口函数用LIMIT
LAG()
函数查看上次排名变化 2025年新趋势:
随着MySQL 8.4的普及,窗口函数性能提升40%,现在连千万级数据排名都能秒级响应!🚀
下次当你需要做排行榜、TopN分析时,不妨掏出这些排名函数,保证让同事直呼"专业!" 😎
ROW_NUMBER
RANK
DENSE_RANK
(注:本文示例基于MySQL 8.4语法,最后更新于2025年8月)
本文由 乐淑贤 于2025-08-01发表在【云服务器提供商】,文中图片由(乐淑贤)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/502093.html
发表评论