SQL窗口函数是数据分析岗面试的核心考点,字节、美团、快手等大厂的数据分析师、数据开发工程师面试几乎必考。窗口函数能力直接决定你能否高效完成排名统计、同环比计算、滑动平均等日常数据分析任务。
先定义窗口函数:对一组与当前行相关的行执行计算,不像GROUP BY那样合并行,而是在保留所有行的同时添加计算列。
讲OVER子句语法:函数() OVER (PARTITION BY 分组列 ORDER BY 排序列 ROWS/RANGE 窗口帧)。
介绍排名函数:ROW_NUMBER()(唯一递增序号)、RANK()(并列排名有间隔)、DENSE_RANK()(并列排名无间隔)。
介绍分析函数:LAG()/LEAD()访问前后行数据、FIRST_VALUE()/LAST_VALUE()取分组首尾值。
介绍聚合窗口函数:SUM/AVG/COUNT配合OVER实现累计求和、移动平均等。
SQL窗口函数是在不改变行数的前提下,对一组相关行进行计算的特殊函数。和GROUP BY不同,窗口函数不会把多行合并成一行,而是在每行旁边新增一个计算列。基本语法是:函数名() OVER (PARTITION BY 分区列 ORDER BY 排序列 窗口帧)。PARTITION BY相当于分组(但不合并行),ORDER BY定义组内排序,窗口帧定义参与计算的行范围。排名函数是最常用的:ROW_NUMBER()给每行一个唯一递增序号,在分组取TopN场景下最常用——比如每个部门工资最高的前3名:SELECT * FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY dept ORDER BY salary DESC) as rn FROM emp) t WHERE rn <= 3。RANK()在遇到并列时给相同排名但跳过后续名次(1,1,3),DENSE_RANK()并列不跳名次(1,1,2)。分析函数中LAG(col, n)取前n行的值,LEAD(col, n)取后n行的值,非常适合计算环比增长:(当月值 - LAG(当月值, 1)) / LAG(当月值, 1)。聚合窗口函数配合ORDER BY可以做累计计算:SUM(amount) OVER(ORDER BY date)实现累计求和;AVG(amount) OVER(ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)实现7日移动平均。窗口帧有ROWS和RANGE两种模式:ROWS基于物理行偏移,RANGE基于逻辑值范围。实际业务中,窗口函数广泛用于排名统计、同环比分析、累计计算、去重(ROW_NUMBER()配合WHERE rn=1)、连续登录天数计算等场景。
分组取TopN是出现频率最高的窗口函数题目,一定要练熟ROW_NUMBER + 子查询的写法。
注意窗口函数不能直接在WHERE中使用,必须套一层子查询或CTE。
准备好LAG/LEAD计算环比增长率的实际SQL写法。
面试写SQL时如果忘了窗口帧语法,即答侠可以实时提示。
假设分数是100,100,90:ROW_NUMBER给1,2,3(强制不同);RANK给1,1,3(并列后跳名次);DENSE_RANK给1,1,2(并列不跳)。
不可以。窗口函数在WHERE之后执行。需要套一层子查询或CTE来过滤窗口函数的结果。
ROWS基于物理行数偏移(前2行就是物理位置上的前2行)。RANGE基于ORDER BY列的值范围(值相同的行被视为同一范围)。大多数场景用ROWS更精确。