You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL 5.7中不使用RANK()和PARTITION BY实现排名功能

MySQL 5.7 适配分组排名功能解决方案

MySQL 5.7 版本不支持RANK()、PARTITION BY这类窗口函数语法,我们可以通过用户自定义变量的方式模拟对应逻辑,实现和参考SQL完全一致的效果,适配语句如下:

SELECT 
  category,
  brands,
  revenue,
  `rank`
FROM (
  SELECT 
    t.*,
    -- 统计当前分类下的行序号,用于实现跳跃排名
    @row_num := IF(@prev_category = category, @row_num + 1, 1) AS temp_row_num,
    -- 同分类同营收排名不变,同分类不同营收取当前行序号作为新排名,跨分类重置排名为1
    @rank := IF(@prev_category = category, 
                IF(@prev_revenue = revenue, @rank, @row_num),
                1) AS `rank`,
    -- 缓存当前行的分类、营收值,用于下一行的对比判断
    @prev_category := category,
    @prev_revenue := revenue
  FROM task.ranking t,
       -- 初始化所有自定义变量
       (SELECT @prev_category := NULL, @prev_revenue := NULL, @rank := 0, @row_num := 0) init
  -- 必须先按分组字段排序,再按排名字段排序,和原窗口函数逻辑一致
  ORDER BY category, revenue
) res
ORDER BY category;

注意事项

  • 内层查询的ORDER BY字段顺序必须严格和原窗口函数的PARTITION BY、ORDER BY字段顺序一致,变量是按排序后的行顺序逐行计算的,顺序错误会导致排名结果不符合预期
  • 变量判断逻辑必须写在变量赋值逻辑之前,避免先把当前行的值覆盖了缓存的上一行值,导致判断出错
  • 如果需要连续排名效果(对应DENSE_RANK()窗口函数),可将@rank的赋值逻辑修改为:
    @rank := IF(@prev_category = category, 
                IF(@prev_revenue = revenue, @rank, @rank + 1),
                1) AS `rank`
    

内容的提问来源于stack exchange,提问作者shalu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:09:01