第3章 高频SQL面试题:窗口函数、复杂查询、优化技巧

SQL是BI开发的核心技能,窗口函数与复杂查询是区分初级与高级工程师的分水岭。面试官通过此类题目考察你对SQL执行逻辑、数据倾斜处理、索引优化、以及业务抽象能力的掌握。本章提炼3道高频面试题,每道题附带考察点、回答框架、示例回答与避坑指南,帮助你系统构建SQL面试应答体系。

窗口函数回答框架(5步拆解法) ① 识别窗口 ② 分区+排序 ③ 选定函数 ④ 边界处理 ⑤ 性能优化 看清楚题目中 “每组、排名、累计” PARTITION BY ROW_NUMBER/DENSE_RANK RANGE/ROWS边界 索引/避免排序

面试问答卡片

高频 面试问题:每个部门工资排名前3的员工信息,如何用SQL实现?
考察点窗口函数语法、DENSE_RANK vs RANK区别、分区与排序、SQL执行顺序
回答框架1. 识别分组(部门)和排序(工资降序)→ 2. 选择DENSE_RANK避免跳过排名 → 3. 子查询过滤排名<=3 → 4. 检查NULL处理与并列情况
示例回答使用DENSE_RANK() OVER(PARTITION BY dept_id ORDER BY salary DESC) AS rnk,外层WHERE rnk<=3。DENSE_RANK保证并列第2时第3名连续,更符合业务需求。
可能追问RANK和DENSE_RANK区别?如果要求每个部门取前3个不同工资呢?如何用自连接实现?
避坑提醒别用ROW_NUMBER直接取前3,会遗漏并列数据;过滤窗口函数必须放到子查询中,否则报错。
窗口函数面试追问路径图 窗口函数使用 排名函数细节 累计/移动平均 边界与窗口帧 性能与索引优化 RANK vs DENSE_RANK vs ROW_NUMBER SUM/AVG + OVER(ORDER BY ... ROWS) RANGE/ROWS/GROUPS区别 文件排序 vs 索引排序
高频 面试问题:查询连续登录超过3天的用户,表含user_id, login_date,如何写SQL?
考察点自连接/窗口函数技巧、连续问题处理思路、滞后/领先函数、去重与日期差计算
回答框架1. 去重日期 → 2. 使用ROW_NUMBER按用户分区日期排序生成rn → 3. 计算date - rn得到分组标志 → 4. 按用户+标志分组计数≥3
示例回答先对每个用户按login_date排序赋序号rn,然后计算login_date - INTERVAL rn DAY,相同差值表示连续日期,分组计数≥3即为连续3天。
可能追问如果允许中断一天也算连续(宽松连续)怎么办?用LAG检查前一天是否相差1?如何处理跨月?
避坑提醒不要忽略重复日期,必须去重;日期减法使用DATE_SUB,注意数据类型;若表很大提前建联合索引。
高频 面试问题:一个SQL查询越来越慢,你如何定位并优化?
考察点执行计划解读、索引利用、数据倾斜处理、改写能力、参数调优经验
回答框架1. EXPLAIN查看扫描行数、索引使用 → 2. 检查where条件是否函数运算导致索引失效 → 3. 分析join顺序与驱动表 → 4. 考虑分区表/物化视图 → 5. 大表分页改用游标或覆盖索引
示例回答先用EXPLAIN发现全表扫描且rows=500万,发现WHERE DATE(create_time)导致索引失效,改为条件区间 '2024-01-01' AND '2024-01-31',扫描行降至2万。
可能追问如何优化关联子查询?慢查询日志如何分析?MySQL vs Hive优化差异?
避坑提醒别盲目加索引,需结合查询模式;避免在索引列使用函数、隐式类型转换;join字段类型必须一致。
💡 本章小结: 窗口函数考察重点在于PARTITION BY与ORDER BY配合,连续问题本质是“日期减序号”分组。SQL优化是开放题,按“定位 → 索引 → 改写 → 架构”递进回答即可体现深度。