sql面试题50题
深度解析SQL核心考点,助你从容应对大厂技术面试
深度解析SQL核心考点,助你从容应对大厂技术面试
在当前的互联网招聘市场中,数据库技能是后端开发、数据分析以及运维工程师的核心竞争力之一。许多企业在招聘流程中,都会设置专门的 sql面试题50题 环节,或者在笔试中大量考察SQL编写能力。这不仅仅是因为SQL是操作数据的通用语言,更因为SQL查询的效率直接决定了整个系统的响应速度和用户体验。
本站整理的 sql面试题50题 并非简单的题目堆砌,而是基于对近五年各大厂(如阿里、腾讯、字节、美团等)面试真题的深度分析。我们将从基础查询到复杂的数据聚合,从索引原理到执行计划分析,全方位覆盖你可能遇到的考点。通过系统性地练习这50道经典题目,你将能够建立起完整的SQL知识体系,并在面试中展现出深厚的技术功底。
在深入复杂题目之前,我们必须夯实基础。以下是 sql面试题50题 中涉及的基础语法深度解析,这些知识点往往隐藏在看似简单的题目背后。
JOIN 是SQL面试中的重灾区。很多求职者知道怎么写 JOIN,但不知道执行顺序和性能差异。在 sql面试题50题 中,至少有10道题涉及复杂的 JOIN 操作。
核心知识点:
这是一个经典面试题。WHERE 在分组前过滤,HAVING 在分组后过滤。WHERE 不能使用聚合函数,而 HAVING 可以。
-- 示例:查询平均薪资大于 10000 的部门
SELECT department_id, AVG(salary) as avg_sal
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 10000;
随着数据分析师职位的兴起,窗口函数(Window Functions)成为了 sql面试题50题 中的新宠。它允许我们在不减少行数的前提下进行聚合计算,非常适合处理排名、累计求和等场景。
在 sql面试题50题 中,经常要求按成绩或销售额排名。这三个函数在处理相同值时的表现不同:
-- 示例:计算每个部门薪资最高的员工
SELECT
FROM (
SELECT name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) as rnk
FROM employees
) t
WHERE rnk = 1;
在金融分析或趋势预测中,我们经常需要计算移动平均线。LEAD 和 LAG 函数可以访问当前行之后的数据或之前的数据。
-- 示例:计算当前销售额与上月销售额的差值
SELECT month, sales,
LAG(sales, 1) OVER (ORDER BY month) as last_month_sales,
sales - LAG(sales, 1) OVER (ORDER BY month) as diff
FROM monthly_sales;
累计求和是窗口函数的经典应用。通过指定 RANGE 或 ROWS 子句,我们可以灵活定义累计的范围。
-- 示例:计算截至当天的累计访问量
SELECT visit_date, visitors,
SUM(visitors) OVER (ORDER BY visit_date ROWS UNBOUNDED PRECEDING) as cumulative_visitors
FROM daily_visits;
对于高级职位,仅仅写出正确的SQL是不够的,面试官更关心SQL的性能。以下是 sql面试题50题 中关于性能优化的核心考点。
在 sql面试题50题 的实战题中,如果数据量达到千万级,不加索引或索引失效会导致查询超时。以下情况会导致索引失效:
当使用 LIMIT 1000000, 10 时,MySQL 需要扫描前 1000010 条记录,效率极低。优化方案是使用“延迟关联”或“游标法”。
-- 优化前:慢
SELECT FROM articles LIMIT 1000000, 10;
-- 优化后:快
SELECT FROM articles a
INNER JOIN (
SELECT id FROM articles LIMIT 1000000, 10
) b ON a.id = b.id;
在回答 sql面试题50题 中的优化问题时,务必提及使用 EXPLAIN 命令。关注以下字段:
| 字段 | 含义 | 理想值 |
|---|---|---|
| type | 访问类型 | const > eq_ref > ref > range > index > ALL |
| key | 实际使用的索引 | 非 NULL |
| rows | 预估扫描行数 | 越小越好 |
| Extra | 额外信息 | 避免 Using filesort, Using temporary |
结合 sql面试题50题 中的真实案例,我们来看几个高频业务场景的解法。
问题描述:用户每天登录,求连续登录3天以上的用户。
解题思路:利用日期差值。对于连续日期,`date - row_number()` 的值是相同的。我们可以按用户分组,计算这个差值,统计出现次数大于等于3的差值。
WITH login_stats AS (
SELECT user_id, login_date,
DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY login_date) DAY) as grp
FROM user_logins
)
SELECT user_id, COUNT() as consecutive_days
FROM login_stats
GROUP BY user_id, grp
HAVING consecutive_days >= 3;
问题描述:每个部门薪资最高的前3名员工。
解题思路:使用窗口函数 ROW_NUMBER 或 DENSE_RANK,然后过滤 rank <= 3。
问题描述:统计各部门薪资,忽略 NULL 值,并将 NULL 显示为 0。
解题思路:使用 COALESCE 或 IFNULL 函数。注意 SUM 会自动忽略 NULL,但 AVG 也会忽略,如果希望将 NULL 视为 0 参与平均计算,需先转换。