LeetCode SQL 必会的 5 个窗口函数:ROW_NUMBER、RANK、DENSE_RANK、LAG、LEAD 一文搞懂

📅 发布时间:2026/7/11 11:26:15
LeetCode SQL 必会的 5 个窗口函数:ROW_NUMBER、RANK、DENSE_RANK、LAG、LEAD 一文搞懂 在刷 LeetCode SQL 时很多题目都会涉及窗口函数Window Function。其中最常用的其实只有 5 个而前三个几乎是每个 SQL 面试都会考察的重点。本文将通过实例讲解这 5 个窗口函数的区别以及适用场景。一、什么是窗口函数普通聚合函数如SUM()、COUNT()会把多行数据聚合成一行。例如SELECT COUNT(*) FROM Employee;返回count10而窗口函数不会减少数据行数而是在保留每一行的基础上计算一个新的结果。例如SELECT name, salary, ROW_NUMBER() OVER(ORDER BY salary DESC) FROM Employee;结果namesalaryrow_numberMax900001Joe850002Henry800003可以看到每一行仍然保留只是多了一列排名。二、5 个最常用的窗口函数1. ROW_NUMBER() —— 连续编号作用给每一行分配唯一编号。SELECT name, salary, ROW_NUMBER() OVER( ORDER BY salary DESC ) AS rn FROM Employee;假设工资如下salary90000850008500069000结果salaryrn900001850002850003690004特点每个人编号唯一即使工资相同也不会并列适用场景每组第一条数据去重最新一条记录2. RANK() —— 排名作用相同值并列但后面的排名会跳号。SELECT salary, RANK() OVER( ORDER BY salary DESC ) AS rnk FROM Employee;结果salaryrank900001850002850002690004注意由于两个员工都是第二名因此下一位直接变成第四名。这就是所谓的跳号排名。3. DENSE_RANK() —— 密集排名作用相同值并列但不会跳号。SELECT salary, DENSE_RANK() OVER( ORDER BY salary DESC ) AS rnk FROM Employee;结果salarydense_rank900001850002850002690003特点相同值排名一致后续排名连续LeetCode 中的「部门工资前三高员工」等题目基本都会使用DENSE_RANK()。例如DENSE_RANK() OVER( PARTITION BY department_id ORDER BY salary DESC )表示每个部门分别进行工资排名。4. LAG() —— 获取上一行数据作用获取当前行前面的第 N 行数据。例如daysales110021503200SQLSELECT day, sales, LAG(sales) OVER( ORDER BY day ) AS prev_sales FROM Sales;结果daysalesprev_sales1100NULL21501003200150常见应用连续登录连续数字环比增长股票涨跌5. LEAD() —— 获取下一行数据作用获取当前行后面的第 N 行数据。SELECT day, sales, LEAD(sales) OVER( ORDER BY day ) AS next_sales FROM Sales;结果daysalesnext_sales110015021502003200NULL常见应用判断下一天是否登录判断下一条记录连续区间问题三、三种排名函数对比假设工资如下salary90000850008500069000ROW_NUMBER()salary结果900001850002850003690004特点不管是否相同编号都不同。RANK()salary结果900001850002850002690004特点相同值并列。后面跳号。DENSE_RANK()salary结果900001850002850002690003特点相同值并列。不跳号。四、如何选择如果你的需求是每条记录一个唯一编号 →ROW_NUMBER()比赛排名允许跳号 →RANK()工资排名、前 N 高不跳号 →DENSE_RANK()获取上一条记录 →LAG()获取下一条记录 →LEAD()五、LeetCode 高频考点下面是刷 LeetCode SQL 时最常见的窗口函数应用函数典型题目ROW_NUMBER()每组第一条数据、去重RANK()比赛排名、成绩排名DENSE_RANK()部门工资前三高、Top N 问题LAG()连续登录、连续数字LEAD()下一次登录、下一条记录其中ROW_NUMBER()、DENSE_RANK()和LAG()的出题频率最高建议优先掌握。总结窗口函数最大的特点就是不减少数据行数而是在每一行上计算一个新的统计结果。记住下面这张表即可函数作用相同值处理ROW_NUMBER()连续编号编号不同RANK()排名并列后面跳号DENSE_RANK()密集排名并列不跳号LAG()上一行数据不是排名LEAD()下一行数据不是排名掌握这 5 个窗口函数基本可以解决 LeetCode SQL 中绝大多数涉及排名、连续记录和 Top N 的题目。