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

MySQL如何实现类似SQL Server的Partition分区排名?求助实现指定逻辑

嘿,作为刚从SQL Server转MySQL的新手,遇到这种排名需求差异太正常了!我来帮你搞定这个分组排名的问题。

首先先明确你的需求:按Name分组,组内按Price从高到低展示,同时Rank值从组内最低Price对应的1开始,递增到最高Price对应的组内行数——简单说就是组内升序Price的排名,倒过来和降序Price一起展示。

方法一:MySQL 8.0+ 用窗口函数(推荐)

MySQL 8.0及以上版本支持窗口函数,这是实现这类需求最简洁高效的方式:

SELECT 
    Name,
    Price,
    ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Price ASC) AS `Rank`
FROM MyTable
ORDER BY Name, Price DESC;

解释:

  • PARTITION BY Name:将数据按Name分组,每个组单独计算排名
  • ORDER BY Price ASC:在每个组内,按Price升序给每行分配序号,这样最低Price的行得到Rank=1,最高Price的行得到组内总行数的序号
  • 外层的ORDER BY Name, Price DESC:让最终结果按Name分组,组内Price从高到低排列,正好对应你要的Rank顺序

方法二:MySQL 5.x 版本用用户变量

如果你的MySQL版本低于8.0,没有窗口函数,可以用用户变量来实现:

-- 初始化变量
SET @prev_name = '';
SET @rank = 1;

SELECT 
    Name,
    Price,
    `Rank`
FROM (
    SELECT 
        Name,
        Price,
        -- 同一组内rank递增,换组则重置为1
        IF(@prev_name = Name, @rank := @rank + 1, @rank := 1) AS `Rank`,
        @prev_name := Name
    FROM MyTable
    -- 先按组内Price升序排序,为rank赋值做准备
    ORDER BY Name, Price ASC
) AS temp_result
-- 最终按组内Price降序输出
ORDER BY Name, Price DESC;

解释:

  1. 先初始化两个变量:@prev_name记录上一行的Name,@rank记录当前排名
  2. 子查询里先按Name和Price升序排序,然后通过IF判断:如果当前行Name和上一行相同,rank加1;否则重置为1
  3. 外层查询再按Name和Price降序排列,得到你想要的结果

这两种方法都能得到你预期的结果,比如qwe组的两个10会分别得到Rank=2和Rank=1,完全符合你的示例需求。

内容的提问来源于stack exchange,提问作者s-dept

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:45:25