SQL窗口函数面试题_WINDOW函数使用分析

7次阅读

窗口函数在保留每行数据基础上叠加计算结果,而普通聚合函数通过group by压缩行;over子句中partition by、order by、rows/range可部分省略但影响逻辑;典型易错点包括混淆排名函数、误用lag/lead、where中引用窗口别名报错。

SQL窗口函数面试题_WINDOW函数使用分析

窗口函数是sql进阶查询的核心能力,面试中常考其逻辑理解、执行顺序和实际场景应用,不是简单背语法就能应付的。

窗口函数和普通聚合函数的区别在哪?

关键在于是否“打散行”:普通GROUP BY会压缩多行成一行,丢失原始行细节;窗口函数则在保留每行数据的基础上,叠加计算结果(如当前行的累计值、排名、前后行差值等)。

典型对比:

  • AVG(salary) FROM emp GROUP BY dept → 每部门只返回1行平均工资
  • AVG(salary) OVER(PARTITION BY dept) → 每员工行都附带其所在部门的平均工资,共N行输出

OVER()子句三要素必须写全吗?

不必须,但缺一不可地影响结果逻辑:

  • PARTITION BY:可省略,默认全表为一个分区(类似没分组)
  • ORDER BY:对多数函数非必需,但对ROW_NUMBER()RANK()SUM() OVER(… ORDER BY …)等排序敏感函数必须存在,否则报错或结果无意义
  • ROWS/RANGE BETWEEN:可省略,此时默认行为依函数而定(如SUM() OVER(ORDER BY t)默认等价于ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

常见的易错点和调试技巧

面试时写错往往不是语法,而是逻辑断层:

  • 混淆RANK()DENSE_RANK()ROW_NUMBER()的并列处理方式——用相同ORDER BY字段查3个函数并排对比,一眼看出差异
  • 误以为LAG(col, 1)能取到“下一行”,其实它是取“上一行”,LEAD()才是向下偏移
  • 在WHERE中直接引用窗口函数别名会报错(如WHERE rn = 1),因为窗口函数在WHERE之后执行——需套一层子查询或CTE再过滤
  • 多个窗口函数共用同一OVER子句时,可提取为winDOW w AS (PARTITION BY x ORDER BY y),提升可读性(部分数据库支持,如postgresqlmysql 8.0+)

一道典型综合题思路拆解

题目:查每个部门薪资第2高的员工(允许并列,取所有第2高者)

解法要点:

  • 先用DENSE_RANK() OVER(PARTITION BY dept ORDER BY salary DESC)生成部门内连续排名
  • 注意不能用ROW_NUMBER()——它会把同薪员工排成不同名次,破坏“第2高”的语义
  • 外层WHERE筛选rank = 2,即可拿到全部符合条件的记录
text=ZqhQzanResources