作者:数分大拿的Statham
一、引言
在数据分析岗位面试中,SQL是必考的核心技能。本文整理了20个高频出现的SQL面试真题,涵盖基础操作、进阶函数和实战场景,特别加入窗口函数等近年热门考点,助您快速掌握通关秘籍!
二、基础篇(5题)
Q1 基础查询与过滤
题目:
查询订单表中2023年交易金额大于5000元的订单ID和用户ID,按金额降序排列。
答案:
SELECT order_id, user_id
FROM orders
WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'
AND amount > 5000
ORDER BY amount DESC;
解析:
-
使用
BETWEEN
简化日期范围判断 -
注意
WHERE
在ORDER BY
前执行
Q2 聚合统计与分组过滤
题目:
计算每个部门的平均薪资,并筛选出平均薪资高于公司整体平均薪资的部门。
答案:
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > (SELECT AVG(salary) FROM employees);
解析:
-
HAVING
过滤聚合结果,不可用WHERE
替代 -
子查询计算全局平均值
Q3 去重与条件判断
题目:
统计用户表中不同年龄段的用户数(分段规则:<20岁、20-30岁、>30岁)。
答案:
SELECT
CASE
WHEN age < 20 THEN 'Under 20'
WHEN age BETWEEN 20 AND 30 THEN '20-30'
ELSE 'Over 30'
END AS age_group,
COUNT(DISTINCT user_id) AS user_count
FROM users
GROUP BY age_group;
Q4 日期函数应用
题目:
查询最近30天内活跃但未下单的用户ID。
答案:
SELECT user_id
FROM user_activity
WHERE last_active_date >= CURRENT_DATE - INTERVAL '30 days'
AND user_id NOT IN (
SELECT DISTINCT user_id
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '30 days'
);
解析:
-
使用
CURRENT_DATE
动态获取当前日期 -
NOT IN
子查询排除下单用户
Q5 字符串处理
题目:
从商品描述字段中提取出所有包含"限量版"关键词的商品ID。
答案:
SELECT product_id
FROM products
WHERE description LIKE '%限量版%';
解析:
-
LIKE
模糊匹配需注意大小写敏感问题 -
建议配合
LOWER()
统一格式:LOWER(description) LIKE '%限量版%'
三、进阶篇(10题)
Q6 多表关联查询(重点!)
题目:
查询购买了"会员服务"但未购买"增值包"的用户名单。
答案:
SELECT DISTINCT u.user_id
FROM users u
JOIN orders o1 ON u.user_id = o1.user_id AND o1.product = '会员服务'
LEFT JOIN orders o2 ON u.user_id = o2.user_id AND o2.product = '增值包'
WHERE o2.order_id IS NULL;
解析:
-
使用
LEFT JOIN + IS NULL
实现反选逻辑 -
避免在
WHERE
直接筛选product
导致逻辑错误
Q7 窗口函数应用(高频考点)
题目:
计算每个用户最近3次消费金额的移动平均值。
答案:
SELECT user_id, order_date, amount,
AVG(amount) OVER (
PARTITION BY user_id
ORDER BY order_date DESC
ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING
) AS moving_avg
FROM orders;
解析:
-
ROWS BETWEEN
定义窗口范围 -
ORDER BY DESC
实现倒序取最近三次
(以下为其他题目示例,完整版需展开)
Q8 分页查询
题目:
查询订单表第21-30条记录(假设每页10条)。
SELECT * FROM orders
ORDER BY order_date DESC
LIMIT 10 OFFSET 20; -- MySQL/PostgreSQL写法
Q9 递归查询(CTE应用)
题目:
查找组织结构表中某个员工的所有上级领导。
WITH RECURSIVE hierarchy AS (
SELECT employee_id, manager_id, 1 AS level
FROM employees WHERE employee_id = 123
UNION ALL
SELECT e.employee_id, e.manager_id, h.level + 1
FROM employees e
JOIN hierarchy h ON e.employee_id = h.manager_id
)
SELECT * FROM hierarchy;
Q10 交叉验证
题目:
验证用户表和订单表的user_id是否完全匹配。
(SELECT user_id FROM users
EXCEPT
SELECT user_id FROM orders)
UNION ALL
(SELECT user_id FROM orders
EXCEPT
SELECT user_id FROM users);
四、高阶挑战篇(5题)
Q11 动态条件查询
题目:
编写可根据输入参数动态筛选状态的存储过程。
CREATE PROCEDURE GetOrders(@status VARCHAR(20) = NULL)
AS
BEGIN
SELECT * FROM orders
WHERE (@status IS NULL OR status = @status)
END;
Q12 数据透视表
题目:
将订单表按月份和产品类型统计销售额。
SELECT
EXTRACT(MONTH FROM order_date) AS month,
SUM(CASE WHEN product_type = 'A' THEN amount ELSE 0 END) AS type_A,
SUM(CASE WHEN product_type = 'B' THEN amount ELSE 0 END) AS type_B
FROM orders
GROUP BY month;
五、避坑指南
常见错误场景 | 解决方案 |
---|---|
混淆WHERE 和HAVING | 记住聚合前过滤用WHERE ,聚合后用HAVING |
JOIN 导致重复数据 | 先聚合再连接或使用DISTINCT |
忽略NULL 值影响 | 使用COALESCE() 设置默认值 |
六、资源推荐
-
《SQL必知必会》 - 快速掌握基础语法
-
LeetCode数据库题库 - 刷题训练神器
-
SQLZoo - 交互式在线练习平台
立即收藏+关注,SQL面试轻松通关! 需要完整20题答案PDF版可在评论区留言⬇️