SQL 基础
入门预计上手 2-4 周星团 数据
岗位需求
1 核心 · 1 加分
在职岗位将其列为技能要求
核心岗位薪资带
15k-30k
核心要求岗位的月薪区间
需求趋势
上升 1稳定 0收缩 0
核心要求岗位的趋势分布
面试题库
高频真题 · 参考答案随题展开1. INNER JOIN、LEFT JOIN、RIGHT JOIN 有什么区别?
INNER JOIN 只返回两表中能匹配上的行,例如订单表连接用户表,只取有对应用户记录的订单。LEFT JOIN 以左表为准,右表匹配不上的字段填 NULL,适合「所有用户及其订单(含未下单用户)」这类保留全量左表的场景。 RIGHT JOIN 相反,以右表为准。还有 FULL JOIN 两边都保留。 典型坑:统计各渠道用户的首单时间用 LEFT JOIN,否则从未下单的渠道会被 INNER JOIN 静默过滤掉,导致渠道覆盖不齐。判断顺序后写反左右表是新手常见错误。 回答时能主动说出「保留哪张表的全部记录」就是抓住了本质。
2. WHERE 和 HAVING 的区别是什么?
WHERE 在分组前过滤行,HAVING 在分组后过滤聚合结果。执行顺序是 FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY,所以 WHERE 里不能用聚合函数和 SELECT 别名,HAVING 主要配合聚合条件。 例如查询下单超过 3 次的用户数:先 WHERE 过滤时间范围和有效订单,再 GROUP BY 用户分组,最后 HAVING COUNT 订单数大于 3。 性能要点是能下推到 WHERE 的条件不要放到 HAVING,先过滤行再做分组计算量更小。 举个对照例子:统计各渠道 3 月下单超过 100 单的用户,WHERE 先限定 3 月有效订单,HAVING 再做计数筛选。 这题几乎必考,答对执行顺序与过滤时机是拿分关键。
3. 什么是窗口函数?举个业务分析的例子。
窗口函数在不折叠行数的前提下,对一组相关行计算结果,语法是 函数 OVER(PARTITION BY 分区字段 ORDER BY 排序字段),常用有 ROW_NUMBER 排名、RANK、DENSE_RANK、LAG 取上一行、SUM 累计求和。 业务例子一:每个用户仅保留最近一次登录记录,按用户分区、按登录时间倒序排号取序号等于 1 的行。 例子二:计算月度 GMV 的累计值与环比,用 SUM OVER 累计、LAG 取上月值。 例子三:给用户消费金额排名打分层标签。窗口函数与 GROUP BY 的区别是保留明细行,是留存、排名、累计类分析的标配。
4. 如何用 SQL 计算次日留存率?请描述思路。
思路是把用户按注册或首活日期分组,再看次日是否活跃。步骤:先构造首活日期表,用 用户 ID 加 MIN 日期 得到每个用户的首活日; 再把每日活跃明细与首活表连接,筛选活跃日期等于首活日期加一天的行为,即得到次日仍活跃的用户;最后按首活日期分组,计算 次日活跃人数除以首活人数。 参考写法是两个 CTE,first_day 用 MIN 函数取首活,active 用 DISTINCT 去重日活,再 LEFT JOIN 并用日期差等于 1 过滤,按日期分组求比率。 面试加分点:提到用 LEFT JOIN 保证无留存日期也显示为零、以及分母口径是新增用户还是活跃用户要澄清。
5. 子查询和 JOIN 各有什么优缺点?什么时候用哪个?
JOIN 适合多表取字段的场景,表达直观、优化器多数情况下表现更好,缺点是多表连接后行数可能膨胀,需要先聚合再连接。 子查询适合做条件过滤与存在性判断,如 WHERE id IN(子查询)或 EXISTS 相关子查询;标量子查询可以当字段用,但每行执行一次时性能差。 经验法则:取字段用 JOIN,判断存在用 EXISTS(比 IN 对 NULL 更安全),先聚合出小结果集再连接大表。 例如统计各城市用户平均客单价,先按用户聚合出人均消费,再连接用户表按城市分组,避免订单和用户直接连接造成的重复计数。
官方文档
1 条最流行的开源数据库官方手册,适合查标准 SQL 语义与函数细节。
推荐教程
2 条边读边练的网页版 SQL 入门教程,适合零基础快速上手查询语法。
经典分主题 SQL 练习站,适合按知识点逐个击破的初学者。
推荐课程
1 条面向数据分析场景的 SQL 课程,适合想系统学数据提取的运营与产品。
上手实践
2 条中文刷题平台的 SQL 专项学习计划,适合面试前集中训练。
基于 PostgreSQL 的全场景题库,适合进阶练习窗口函数与聚合。
难度档决定星等与难度分权重(入门 1 / 进阶 2 / 精通 3);学习资源由编辑部遴选并持续维护, 经验心得欢迎在上方「知识分享」区署名分享。

