题解 | 查询用户刷题日期和下一次刷题日期(窗口函数基础)

查询用户刷题日期和下一次刷题日期

https://www.nowcoder.com/practice/fed7ebf4254240fdb6a2c963996ee8ff

select user_id, date, lead(date,1) over(
    partition by user_id order by date) nextdate
from questions_pass_record
order by user_id, date

窗口函数(Window Function)是 SQL 中用于在一组与当前行相关的行上执行计算的强大工具,它不会像聚合函数那样将多行合并为一行,而是保留每行的独立结果,同时附加基于 “窗口”(即指定范围的行)的计算结果。

一、窗口函数的基本语法

sql

窗口函数名(列名) OVER (
    [PARTITION BY 列名1, 列名2...]  -- 分区(可选):将数据按列分组,每组独立计算
    [ORDER BY 列名 [ASC|DESC]]      -- 排序(可选):定义窗口内的行顺序
    [ROWS|RANGE BETWEEN 边界1 AND 边界2]  -- 窗口范围(可选):指定窗口包含的行范围
)

  • 核心作用:在不聚合行的前提下,实现 “分组内排序”“组内排名”“累计计算” 等需求。
  • 与聚合函数的区别:聚合函数(如 SUM)会将分组后的多行合并为一行,而窗口函数会为每行返回一个结果,同时保留原始行的所有信息。

二、常用知识点

  1. 分区(PARTITION BY)类似 GROUP BY,但不合并行,而是将数据划分为多个 “窗口”(组),每个窗口独立计算。若不指定 PARTITION BY,则整个表视为一个窗口。
  2. 排序(ORDER BY)定义窗口内的行顺序,是排名类、累计类函数的基础(如 RANK、SUM() OVER (ORDER BY ...))。
  3. 窗口范围(ROWS/RANGE)用于精确指定窗口包含哪些行(默认范围因函数而异):
  • ROWS:按物理行数定义范围(如 ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING 表示当前行 + 前 1 行 + 后 1 行)。
  • RANGE:按逻辑值范围定义(如 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 表示从窗口第一行到当前行)。
  • 常见简写:
  • CURRENT ROW:当前行
  • UNBOUNDED PRECEDING:窗口第一行
  • UNBOUNDED FOLLOWING:窗口最后一行

三、常用窗口函数分类

1. 排名函数(用于分组内排序)

  • RANK():分组内排名,存在并列时跳过后续名次(如 1,1,3)。
  • DENSE_RANK():分组内排名,存在并列时不跳过后续名次(如 1,1,2)。
  • ROW_NUMBER():分组内按顺序生成唯一序号(无并列,即使值相同也按顺序编号 1,2,3)。

2. 聚合类窗口函数(用于累计 / 分组内统计)

将常见聚合函数(SUMAVGMAXMIN 等)作为窗口函数,计算窗口内的聚合结果。

  • SUM():累计求和
  • AVG():滑动平均值(如近 3 天平均销售额)
  • MAX()/MIN():分组内最大 / 最小值

3. 偏移函数(用于获取相邻行数据)

  • LAG(列名, n):获取当前行的前 n 行数据(默认 n=1)。
  • LEAD(列名, n):获取当前行的后 n 行数据。

4. 其他常用函数

  • FIRST_VALUE(列名):获取窗口内的第一行数据。
  • LAST_VALUE(列名):获取窗口内的最后一行数据(注意默认窗口范围可能需要显式指定)。
全部评论

相关推荐

头像
2025-12-27 13:01
三峡大学 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务