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

如何用SQL根据积分查询用户排行榜名次?含重复用户及同积分问题

解决profile表排行榜同积分同名次的问题

嘿,我懂你的烦恼!当两个用户积分相同时,用count函数确实会把名次给错开,完全不符合咱们想要的“同积分同排名”效果。咱们换个更靠谱的思路,用窗口函数来搞定,既能精准取到每个用户的最新记录,又能完美处理同积分的排名逻辑,一步到位!

第一步:先筛选每个用户的最新记录

首先得把每个用户最新(对应max(lastupdated))的那条数据捞出来,毕竟用户可能多次存入表中。这里用ROW_NUMBER()窗口函数最省心:

WITH latest_profiles AS (
    SELECT 
        Id,
        profilename,
        points,
        lastupdated,
        -- 按用户ID分组,更新时间倒序排列,最新的那条标记为rn=1
        ROW_NUMBER() OVER (PARTITION BY Id ORDER BY lastupdated DESC) AS rn
    FROM profile
)
SELECT Id, profilename, points
FROM latest_profiles
WHERE rn = 1

这个CTE(公共表表达式)会给每个用户的所有记录按更新时间排序,只保留最新的那一行,这样咱们就拿到了干净的、每个用户唯一的最新积分数据。

第二步:计算同积分同名次的排行榜

接下来就是核心的排名环节了,别再用count硬凑了,RANK()或者DENSE_RANK()窗口函数天生就是干这个的:

  • RANK():如果有两个第1名,下一个名次会直接跳到第3名(跳过重复的名次)
  • DENSE_RANK():如果有两个第1名,下一个名次是第2名(不跳过名次)

你可以根据自己的需求二选一,完整的SQL代码如下:

WITH latest_profiles AS (
    SELECT 
        Id,
        profilename,
        points,
        ROW_NUMBER() OVER (PARTITION BY Id ORDER BY lastupdated DESC) AS rn
    FROM profile
),
ranked_profiles AS (
    SELECT 
        profilename,
        points,
        -- 按积分倒序排序,相同积分自动分配相同名次
        RANK() OVER (ORDER BY points DESC) AS rank_position
        -- 要是想要不跳过名次的逻辑,就换成下面这句:
        -- DENSE_RANK() OVER (ORDER BY points DESC) AS rank_position
    FROM latest_profiles
    WHERE rn = 1
)
SELECT profilename, points, rank_position
FROM ranked_profiles
ORDER BY rank_position ASC;

为啥之前的count方法会出问题?

举个简单例子:如果有两个用户都是100分,用count统计“比当前用户积分高的人数+1”的话,理论上能得到第1名,但如果你的SQL逻辑没处理好(比如误加了distinct或者关联条件不对),就会导致第二个100分的用户名次变成第2名。而RANK()这类窗口函数会自动识别相同的积分值,直接给它们分配相同的名次,完全不用手动凑逻辑,靠谱得多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:30:27