导读:本期聚焦于小伙伴创作的《SQL窗口函数面试题常考哪些?WINDOW函数使用场景与分析方法详解》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《SQL窗口函数面试题常考哪些?WINDOW函数使用场景与分析方法详解》有用,将其分享出去将是对创作者最好的鼓励。

SQL窗口函数是数据库查询中用于处理分组内数据的高阶功能,它能在不改变原表行数的前提下,对每组数据进行计算并返回结果,在数据分析、报表统计等场景中应用十分广泛,也是技术面试中数据库相关岗位的高频考察点。

SQL窗口函数面试题常考哪些?WINDOW函数使用场景与分析方法详解

什么是SQL窗口函数

窗口函数也叫分析函数,它和聚合函数的区别在于,聚合函数会将多行数据聚合成一行,而窗口函数会为每一行数据返回一个计算结果,同时保留原表的所有行。窗口函数的基本语法结构如下:

-- 窗口函数基本语法
函数名(参数) OVER (
    [PARTITION BY 分组列]
    [ORDER BY 排序列 [ASC|DESC]]
    [窗口范围]
)

其中OVER子句是窗口函数的核心,用来定义数据的窗口范围,PARTITION BY用来指定分组的列,ORDER BY用来指定组内排序的规则,窗口范围可以指定计算的数据范围,比如从当前行往前数几行等。

常见窗口函数分类

面试中常考的窗口函数主要分为以下几类:

  • 排名类窗口函数:包括ROW_NUMBER()RANK()DENSE_RANK(),用来对数据进行排名
  • 聚合类窗口函数:包括SUM()AVG()COUNT()等聚合函数结合OVER子句使用,用来计算累计、移动聚合值
  • 取值类窗口函数:包括LAG()LEAD()FIRST_VALUE()LAST_VALUE(),用来获取相邻行或者组内首尾行的数据

高频面试题与解题思路

面试题1:查询每个部门薪资最高的前两名员工

这类排名问题是窗口函数最典型的考察场景,我们可以根据需求选择对应的排名函数:

-- 创建测试员工表
CREATE TABLE employee (
    id INT,
    name VARCHAR(50),
    dept VARCHAR(50),
    salary INT
);

-- 插入测试数据
INSERT INTO employee VALUES
(1, '张三', '技术部', 12000),
(2, '李四', '技术部', 15000),
(3, '王五', '技术部', 15000),
(4, '赵六', '产品部', 10000),
(5, '钱七', '产品部', 13000),
(6, '孙八', '产品部', 11000);

-- 查询每个部门薪资最高的前两名员工,使用DENSE_RANK避免并列薪资跳过排名
SELECT 
    id,
    name,
    dept,
    salary,
    rk
FROM (
    SELECT 
        id,
        name,
        dept,
        salary,
        DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rk
    FROM employee
) t
WHERE rk <= 2;

这里需要注意三个排名函数的区别:ROW_NUMBER()会生成连续不重复的排名,即使薪资相同也会排不同名次;RANK()遇到相同值会并列排名,下一个排名会跳过占用的名次;DENSE_RANK()并列排名后下一个排名不会跳过,更符合取前N名不限制人数的需求。

面试题2:计算每个月的累计销售额

这类累计计算问题适合使用聚合类窗口函数,通过指定窗口范围实现累计统计:

-- 创建销售表
CREATE TABLE sales (
    month VARCHAR(10),
    amount INT
);

-- 插入测试数据
INSERT INTO sales VALUES
('2024-01', 1000),
('2024-02', 1500),
('2024-03', 1200),
('2024-04', 1800);

-- 计算每月累计销售额
SELECT 
    month,
    amount,
    SUM(amount) OVER (ORDER BY month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total_amount
FROM sales;

这里的窗口范围ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW表示从第一行到当前行的所有数据,也就是累计计算的逻辑。如果不指定窗口范围,默认就是整个分组内的所有行,同样可以实现累计效果。

面试题3:查询每个用户相邻两次登录的时间间隔

这类需要获取相邻行数据的场景,适合使用LAG()或者LEAD()函数:

-- 创建用户登录表
CREATE TABLE user_login (
    user_id INT,
    login_time DATETIME
);

-- 插入测试数据
INSERT INTO user_login VALUES
(1, '2024-03-01 10:00:00'),
(1, '2024-03-03 14:00:00'),
(1, '2024-03-05 09:00:00'),
(2, '2024-03-02 11:00:00'),
(2, '2024-03-04 16:00:00');

-- 查询每个用户相邻两次登录的时间间隔
SELECT 
    user_id,
    login_time,
    LAG(login_time) OVER (PARTITION BY user_id ORDER BY login_time) AS last_login_time,
    TIMESTAMPDIFF(DAY, LAG(login_time) OVER (PARTITION BY user_id ORDER BY login_time), login_time) AS login_interval
FROM user_login;

LAG(列名, n)用来获取当前行往前第n行的数据,默认n为1,LEAD()则是获取往后第n行的数据,这两个函数在处理时间序列相关的相邻数据问题时非常实用。

窗口函数使用注意事项

  • 窗口函数只能出现在SELECT子句和ORDER BY子句中,不能出现在WHEREGROUP BY等子句中
  • 如果OVER子句中没有PARTITION BY,则默认将整张表作为一个分组
  • 不同数据库的窗口函数支持程度略有差异,比如MySQL从8.0版本才开始支持窗口函数,使用时需要确认数据库版本
  • 在使用排名函数时,一定要明确业务需求,选择合适的排名函数,避免结果不符合预期
窗口函数的核心逻辑是定义好数据的分组和排序规则,再根据需求选择对应的函数,多结合业务场景练习就能快速掌握其使用技巧,应对面试中的相关问题也会更加轻松。

SQL窗口函数窗口函数面试题WINDOW函数SQL分析函数修改时间:2026-07-13 18:39:34

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。