SQL 手写实战题

共 19 题
#

1. 手写 SQL,查询每个部门工资第二高的员工(考虑并列与不存在的情况),窗口函数与相关子查询两种写法?

A 只能用窗口函数
B 窗口函数用 DENSE_RANK 排名取 rn=2,相关子查询可自连接比较,并列算同一名次用 DENSE_RANK ✓ 正确答案
C 只能用相关子查询
D 无法处理并列
#

2. 手写 SQL,统计连续登录 ≥3 天的用户(日期减行号分组法),并说明该技巧的推广场景?

A 日期减行号分组法把连续日期归为同组,聚合计数判断连续天数 ✓ 正确答案
B 该方法无法统计连续
C 只能用于登录
D 用 MAX 判断连续
#

3. 手写 SQL,计算次日留存率/7 日留存率(自关联与窗口两种写法)?

A 留存率 = 次日活跃/当日活跃
B 留存率 = 首日活跃用户在 N 日后仍活跃的比例,可用自关联或窗口(MIN 首日)实现 ✓ 正确答案
C 留存率无法计算
D 用 SUM 计算
#

4. 手写 SQL,行转列(成绩表科目透视)与列转行的标准写法(CASE WHEN/PIVOT/UNION ALL)?

A 行转列用 CASE WHEN 条件聚合或 PIVOT,列转行用 UNION ALL 或 UNPIVOT,CASE WHEN 最可移植 ✓ 正确答案
B 行转列用 UNION ALL
C 两者都用 PIVOT
D 列转行用 CASE WHEN
#

5. 手写"连续登录 N 天"的用户 SQL,日期去重、窗口函数与分组技巧?

A 无需去重
B 先日期去重,再窗口编号,日期减行号分组,计数 >= N ✓ 正确答案
C 用 SUM 判断
D 无法判断
#

6. 手写"求每个部门薪资 Top3",窗口函数 row_number vs 自连接实现对比?

A 窗口函数简洁高效,自连接复杂低效 ✓ 正确答案
B 自连接更简洁
C 两者等价
D 只能用自连接
#

7. 手写 SQL,求中位数与众数(PERCENTILE_CONT 窗口与自连接两种写法)

A 众数用 MIN
B 中位数用 MAX
C 中位数用 PERCENTILE_CONT(0.5),众数用分组计数取最多 ✓ 正确答案
D 两者无法计算
#

8. 手写 SQL,查询每个用户最近一次订单(窗口 ROW_NUMBER vs 关联子查询 vs 组内 MAX 回连三种写法的性能对比)?

A 三者性能相同
B 关联子查询最优
C 窗口函数一次扫描最优,关联子查询逐行最差,MAX 回连中等 ✓ 正确答案
D MAX 回连最差
#

9. 手写 SQL,找出连续区间(如连续的座位号/日期段的起止),gaps-and-islands 问题的通用解法?

A 用 MAX 排序
B 用 序号-行号 分组,同组为连续区间,取 MIN/MAX 得起止 ✓ 正确答案
C 无法识别连续区间
D 用 SUM 分组
#

10. 手写 SQL,去重保留最新一条记录并删除其余重复行的安全写法?

A 直接删所有重复
B 用 GROUP BY 删除
C 无法保留最新
D 用 ROW_NUMBER 按时间排序保留 rn=1,删除 rn>1,先验证再删 ✓ 正确答案
#

11. 手写"同比/环比"SQL,LAG 窗口与日期对齐的边界处理?

A 环比用 LAG(1) 取上期,同比用 LAG 按周期对齐取同期,边界需处理 NULL ✓ 正确答案
B 都用 LAG(1)
C 同环比用 LEAD
D 无法计算
#

12. 手写"行列转换"(PIVOT/UNPIVOT)与字符串聚合(GROUP_CONCAT)的实现?

A 无法转换
B 都用 GROUP_CONCAT
C 行转列用 CASE WHEN/PIVOT,列转行用 UNION ALL/UNPIVOT,字符串聚合用 GROUP_CONCAT/STRING_AGG ✓ 正确答案
D 字符串聚合用 PIVOT
#

13. TopN 分组查询,每个部门薪资前三名的窗口函数写法?

A 用 GROUP BY 取前三
B 用 ROW_NUMBER OVER (PARTITION BY dept ORDER BY salary DESC) 取 rn<=3 ✓ 正确答案
C 用 MAX 取前三
D 无法分组 TopN
#

14. 手写 SQL,组织架构树的递归展开(WITH RECURSIVE)与层级缩进

A 用 GROUP BY 展开
B 用递归 CTE 锚成员取根、递归成员连子节点带 depth,缩进用 REPEAT 按 depth 前缀 ✓ 正确答案
C 无法递归
D 缩进用 MAX
#

15. 手写 SQL,大表分批 UPDATE/DELETE(按主键范围切片)避免长事务与锁表

A 锁表无关
B 一次全量更新
C 只能不分批
D 按主键切片分批 UPDATE/DELETE,每批提交,避免长事务与锁表 ✓ 正确答案
#

16. 手写 SQL,累计求和(running total)与移动平均的窗口写法?

A 累计和用 UNBOUNDED PRECEDING 帧,移动平均用 n PRECEDING 帧 ✓ 正确答案
B 两者用相同帧
C 都只能用 GROUP BY
D 无法窗口计算
#

17. 手写"库存扣减"的原子 SQL,条件更新与乐观锁的写法?

A 并行即可
B 用 SELECT 后 UPDATE
C 无法防超卖
D 条件更新用 WHERE quantity >= N 防超卖,乐观锁用 version 比较防并发冲突 ✓ 正确答案
#

18. 同比环比与累计,LAG/SUM OVER 的 SQL 实现?

A 无法实现
B 全部用 SUM
C LAG 取前后期值算同比环比,SUM OVER 做累计 ✓ 正确答案
D 用 MAX
#

19. 手写 SQL,随机抽样(ORDER BY RANDOM() vs TABLESAMPLE)的性能差异

A ORDER BY RANDOM() 全表排序慢,TABLESAMPLE 只读采样块快,大表用 TABLESAMPLE ✓ 正确答案
B TABLESAMPLE 更慢
C 两者相同
D ORDER BY RANDOM 更快