AI大模型教程
一起来学习

SQL93 查询每天刷题通过数最多的前二名用户id和刷题数

描述

现有牛客刷题表`questions_pass_record`,请查询每天刷题通过数最多的前二名用户id和刷题数,输出按照日期升序排序,查询返回结果名称和顺序为

date|user_id|pass_count

 

SELECT date, user_id, pass_count
FROM (
    SELECT user_id, pass_count,date,
           ROW_NUMBER() OVER (PARTITION BY date ORDER BY pass_count DESC) AS rk
    FROM questions_pass_record
) AS t
WHERE rk 

第一步:内层子查询(核心逻辑)

SELECT 
    user_id, 
    pass_count, 
    date,
    ROW_NUMBER() OVER (PARTITION BY date ORDER BY pass_count DESC) AS rk
FROM questions_pass_record

这是整个查询的核心,使用了 窗口函数(Window Function)

✅ ROW_NUMBER() OVER (...) 是什么?

这是一个排序函数,它会给每一行分配一个唯一的序号(从 1 开始)。

我们来拆解括号里的内容:


🟦 PARTITION BY date
  • 意思是:按日期分组
  • 把数据按照 date 切成多个“小块”(每一天一块)。
  • 每一天内部独立进行排序。

👉 就像把全班同学按“考试日期”分成不同考场,每个考场单独排名。


🟨 ORDER BY pass_count DESC
  • 在每个“日期分组”内部,按 pass_count(通过题数)从高到低排序
  • DESC 表示降序(大 → 小),所以通过题数最多的排在最前面。

🟩 ROW_NUMBER() ... AS rk
  • 给每行打上一个排名编号:
    • 当天 pass_count 最高的 → rk = 1
    • 第二高的 → rk = 2
    • 第三高的 → rk = 3,以此类推

📌 注意:ROW_NUMBER() 是“连续且不重复”的,即使两个人分数一样,也会强行分出 1 和 2。

第二步:外层查询(筛选 Top 2)

SELECT date, user_id, pass_count
FROM ( ... 上面的结果叫 t ... )
WHERE rk 
  • 我们把内层查询的结果当作一张临时表 t
  • 然后从中选出 rk  的记录,也就是:
  • 每天排名前两名的用户。

三种排序方式详解

1. ROW_NUMBER()

  • 特点:给每一行分配一个唯一的序号,从 1 开始,连续递增。
  • 相同值怎么办?即使 pass_count 相同(如 B 和 C 都是 9),也会强行分出先后(2 和 3)。
  • 适用场景
    • 需要唯一编号;
    • 不允许重复排名;
    • 比如“取前 N 条记录”,即使并列也要限制数量。

💡 小贴士:如果有并列数据,ROW_NUMBER() 的顺序是不确定的(除非再加 ORDER BY 细化)。


2. RANK()

  • 特点:标准竞赛排名规则。
  • 相同值:并列同一名次;
  • 后续名次:跳过相应的数量。

👉 例子中:

  • A 是第 1 名;
  • B 和 C 并列第 2 名;
  • D 是第 4 名(因为前面有 3 个人,但只有两个名次被占用:1 和 2)。

🏆 就像奥运会:两人并列银牌,就没有铜牌。

  • 适用场景
    • 想体现“并列排名”;
    • 接受名次跳跃;
    • 比如“找出所有成绩不低于第2名的用户”。

3. DENSE_RANK()

  • 特点:紧密排名,不跳过名次。
  • 相同值:并列同一名次;
  • 后续名次:+1。

👉 例子中:

  • A:第 1 名;
  • B 和 C:第 2 名;
  • D:第 3 名。

🎯 更像是“等级制”:第1级、第2级、第3级……

  • 适用场景
    • 想知道“这是第几档水平”;
    • 不希望名次断层;
    • 比如“取前3个等级的用户”。

文章来源于互联网:SQL93 查询每天刷题通过数最多的前二名用户id和刷题数

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » SQL93 查询每天刷题通过数最多的前二名用户id和刷题数
分享到: 更多 (0)

AI大模型,我们的未来

小欢软考联系我们