【面试通关】大数据开发高频SQL面试题(含详细解析)------in/exists、having/where、排序函数等核心考点
摘要
本文整理了大数据开发面试中最高频的SQL核心考点,聚焦in与exists、having与where、窗口排序函数、on与where表连接等易混淆知识点,通过「问题+核心区别+实战案例」的形式,清晰拆解每个考点的底层逻辑和使用场景,帮助面试者快速掌握解题思路,避开高频踩坑点,适用于Hive/Spark SQL/Oracle等主流大数据SQL场景。
正文
一、基础核心区别类(高频必问)
1. 请详细说明 IN 和 EXISTS 的区别,以及各自的适用场景
考察点 :子查询执行逻辑、性能优化、数据量适配
参考答案:
-
核心区别:
① 执行逻辑:IN是「外查询→内查询」,先执行内查询得到结果集,外查询匹配结果集;EXISTS是「内查询→外查询」,内查询只需返回是否存在记录(布尔值),无需返回完整结果集。
② 空值处理:IN遇NULL会返回NULL(导致结果丢失),EXISTS遇NULL仍可正常判断是否存在。
③ 性能差异:内查询结果集小→用IN;外查询数据量小、内查询需关联字段→用EXISTS(大数据场景下EXISTS更适合大表关联)。 -
实战案例:
sql-- IN:内查询结果集小时使用 SELECT * FROM emp WHERE deptno IN (SELECT deptno FROM dept WHERE loc = '北京'); -- EXISTS:大表关联时更高效 SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM dept d WHERE e.deptno = d.deptno AND d.loc = '北京');
2. WHERE 和 HAVING 的核心区别是什么?分别在什么场景下使用?
考察点 :数据过滤阶段、聚合函数使用限制
参考答案:
-
核心区别:
① 过滤阶段:WHERE在「分组前」过滤行,不允许使用聚合函数;HAVING在「分组后」过滤分组结果,必须配合GROUP BY使用,可使用聚合函数。
② 适用字段:WHERE只能过滤表中原始字段;HAVING可过滤聚合后的计算字段(如SUM/COUNT/AVG结果)。 -
实战案例:
sql-- WHERE:分组前过滤(只查部门10的员工) SELECT deptno, AVG(sal) FROM emp WHERE deptno = 10 GROUP BY deptno; -- HAVING:分组后过滤(只查平均工资>5000的部门) SELECT deptno, AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal) > 5000;
3. 表连接中 ON 和 WHERE 的区别?左连接场景下为什么不能随便替换?
考察点 :连接逻辑、NULL值处理、左连接/右连接特性
参考答案:
-
核心区别:
① 执行阶段:ON是「连接时」过滤(先筛选符合条件的行再连接),WHERE是「连接后」过滤(先全量连接再筛选)。
② 左连接影响:左连接中,ON过滤不影响左表主数据(不符合ON条件的左表行仍保留,右表字段为NULL);WHERE过滤会直接剔除不符合条件的行(包括左表行)。 -
实战案例:
sql-- 错误:WHERE过滤导致左表无匹配的行被剔除 SELECT e.ename, d.dname FROM emp e LEFT JOIN dept d ON e.deptno = d.deptno WHERE d.loc = '北京'; -- 正确:ON过滤只筛选右表,左表行完整保留 SELECT e.ename, d.dname FROM emp e LEFT JOIN dept d ON e.deptno = d.deptno AND d.loc = '北京';
二、窗口函数类(大数据开发重点)
4. ROW_NUMBER()、RANK()、DENSE_RANK() 的区别?请举例说明使用场景
考察点 :排序逻辑、重复值处理、TopN场景适配
参考答案:
-
核心区别(以分数排序为例):
① ROW_NUMBER():连续编号,重复值也会分配不同序号(如90、90、80→1、2、3)。
② RANK():跳跃编号,重复值共享序号,后续序号跳跃(如90、90、80→1、1、3)。
③ DENSE_RANK():连续编号,重复值共享序号,后续序号连续(如90、90、80→1、1、2)。 -
实战案例(取每个部门工资前2的员工):
sqlSELECT ename, deptno, sal, ROW_NUMBER() OVER(PARTITION BY deptno ORDER BY sal DESC) AS rn, RANK() OVER(PARTITION BY deptno ORDER BY sal DESC) AS rk, DENSE_RANK() OVER(PARTITION BY deptno ORDER BY sal DESC) AS dr FROM emp;
5. LAG() 和 LEAD() 函数的作用?请结合场景说明用法(如计算用户连续登录天数/成绩环比)
考察点 :窗口函数取值逻辑、跨行数据处理
参考答案:
-
核心作用:
① LAG(col, n):取当前行「前n行」的指定字段值(默认n=1)。
② LEAD(col, n):取当前行「后n行」的指定字段值(默认n=1)。 -
实战案例(计算学生成绩环比变化):
sqlSELECT sno, cla, score, LAG(score, 1) OVER(PARTITION BY sno ORDER BY cla) AS last_score, -- 上一科成绩 score - LAG(score, 1) OVER(PARTITION BY sno ORDER BY cla) AS diff -- 成绩变化 FROM t_score;
三、性能优化类(进阶考点)
6. 大数据场景下,如何优化包含 IN/EXISTS 的慢SQL?
参考答案:
- 优先用EXISTS替代IN(尤其是内查询结果集大时),EXISTS只需判断存在性,无需返回全量数据;
- 内查询结果集去重(DISTINCT),减少匹配次数;
- 给关联字段加索引(如Hive中给分区字段/关联字段建索引,Spark中优化Shuffle);
- 大数据量时,用JOIN替代IN(IN底层会转为JOIN,但手动JOIN可更精准控制)。
7. 窗口函数在大数据场景(Hive/Spark)中的性能优化技巧?
参考答案:
- 尽量缩小PARTITION BY的范围(避免全表分区);
- 排序字段优先用整型/日期型,减少字符串排序开销;
- Hive中开启矢量化执行(set hive.vectorized.execution.enabled=true);
- Spark中调整shuffle分区数(spark.sql.shuffle.partitions),避免数据倾斜。