重难点复盘|多表 + 子查询真题演练,吃透核心(附面试真题)
前言到本篇为止我们已经完整学完了企业 SQL 80% 核心重难点INNER/LEFT/RIGHT/FULL JOIN 多表联查、标量 / 列 / 行子查询、EXISTS/IN/ANY/ALL、UNION/UNION ALL 联合查询。这些内容是面试必考、工作高频、拉开差距的关键。这一篇不讲新知识点专门做高强度复盘 真题集训把前面所有重难点串成体系、用企业真实面试题带你彻底吃透做到学完就会、会了能用、用了不踩坑。一、本章知识点汇总四大连接类型核心原理一句话总结子查询三大类型 四大关键字速记清单UNION 与 UNION ALL必背区别笛卡尔积、NULL、关联顺序三大坑点复盘企业高频面试真题10 道 详细答案多表 子查询混合实战综合题职场书写规范与优化黄金原则重难点思维导图式总结下一步学习路线指引二、重难点速记复盘背会直接面试1. 四大连接速记INNER JOIN取交集只保留两边匹配数据LEFT JOIN左表全保留右表不匹配补 NULL工作最常用RIGHT JOIN右表全保留可转为 LEFT JOIN 写FULL JOIN两边全保留MySQL 用 UNION 实现黄金原则90% 场景用LEFT JOIN主表永远放左边。2. 子查询速记标量子查询返回 1 个值用 列子查询返回一列用IN/ANY/ALL行子查询返回一行多列(a,b)(子查询)EXISTS只判断存在大表性能最强IN小表好用大表慎用NOT IN有 NULL 陷阱生产禁用NOT EXISTS查询不存在数据的唯一安全写法黄金原则大表关联用EXISTS非存在用NOT EXISTS。3. 联合查询速记UNION合并 去重 排序慢UNION ALL直接合并极快语法铁律列数相同、类型兼容、顺序一致排序只在最后写一次 ORDER BY黄金原则生产默认UNION ALL。4. 三大致命坑复盘笛卡尔积漏写 ON、一对多无分组 → 数据爆炸NULL 陷阱NOT IN、判断空值用NULL→ 结果错误连接顺序错误跳表连接、主从表颠倒 → 结果不对 / 性能差三、企业高频面试真题10 道真题 1LEFT JOIN 与 INNER JOIN 区别答案 INNER JOIN 只返回两张表交集 LEFT JOIN保留左表全部数据右表不匹配补 NULL是企业最常用连接。真题 2为什么不推荐使用 RIGHT JOIN答案 RIGHT JOIN 逻辑可读性差所有 RIGHT JOIN 都可以换成 LEFT JOIN企业统一规范只用 LEFT JOIN便于维护。真题 3UNION 与 UNION ALL 区别哪个快答案 UNION 会去重并排序速度慢 UNION ALL直接拼接速度远快于 UNION生产优先使用。真题 4EXISTS 与 IN 怎么选答案 小表用 IN大表关联必用 EXISTS EXISTS 只判断存在匹配到即停止性能更高。真题 5NOT IN 有什么坑怎么解决答案 子查询返回 NULL 时NOT IN 结果永远为空。 必须用NOT EXISTS替代。真题 6什么是笛卡尔积怎么避免答案 多表连接无关联条件导致全表匹配数据量爆炸。 避免每层 JOIN 必须写 ON用主键 外键关联先过滤再连接。真题 7左连接中右表条件放 ON 还是 WHERE答案 右表条件放ON不影响左表保留 放 WHERE 会过滤左表等价于内连接。真题 8子查询有哪几种类型答案 按结果分标量、列、行子查询。 按关键字分IN/ANY/ALL/EXISTS。真题 9如何查询 “没有下单的用户”答案sqlSELECT * FROM users u WHERE NOT EXISTS ( SELECT 1 FROM orders o WHERE o.user_idu.user_id );真题 10多表连接统计时为什么要用 COUNT (DISTINCT)答案 一对多连接会导致行数膨胀直接 COUNT 会重复计算必须用 DISTINCT 去重。四、综合实战环境直接复制运行sql-- 用户表 CREATE TABLE users ( user_id INT PRIMARY KEY, user_name VARCHAR(20) NOT NULL ); -- 订单表 CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, amount DECIMAL(10,2), order_time DATE ); -- 商品表 CREATE TABLE goods ( goods_id INT PRIMARY KEY, goods_name VARCHAR(30), price DECIMAL(10,2) ); -- 订单明细表 CREATE TABLE order_item ( id INT PRIMARY KEY AUTO_INCREMENT, order_id INT, goods_id INT, num INT ); INSERT INTO users VALUES (1,张三),(2,李四),(3,王五),(4,赵六); INSERT INTO orders VALUES (1001,1,299,2024-06-01), (1002,2,420,2024-06-02), (1003,3,88,2024-06-03); INSERT INTO goods VALUES (1,笔记本,299),(2,键盘,159),(3,T恤,99); INSERT INTO order_item VALUES (1,1001,1,1),(2,1002,3,1),(3,1003,2,1);五、综合实战大题企业标准难度综合题 1四表联查 统计查询所有用户的 用户名、订单数、商品总数、总消费金额无消费显示 0。sqlSELECT u.user_id, u.user_name, COUNT(DISTINCT o.order_id) AS order_cnt, COALESCE(SUM(oi.num),0) AS total_goods, COALESCE(SUM(oi.num * g.price),0) AS total_amount FROM users u LEFT JOIN orders o ON u.user_id o.user_id LEFT JOIN order_item oi ON o.order_id oi.order_id LEFT JOIN goods g ON oi.goods_id g.goods_id GROUP BY u.user_id, u.user_name ORDER BY total_amount DESC;综合题 2子查询 EXISTS 优化查询买过 “笔记本” 的用户用 EXISTS性能最优。sqlSELECT * FROM users u WHERE EXISTS ( SELECT 1 FROM orders o JOIN order_item oi ON o.order_idoi.order_id JOIN goods g ON oi.goods_idg.goods_id WHERE o.user_idu.user_id AND g.goods_name笔记本 );综合题 3联合查询 报表汇总合并订单表统计 线上总金额、线下总金额、总金额模拟两表合并。sqlSELECT 订单总金额 AS type, SUM(amount) FROM orders UNION ALL SELECT 商品总销售额 AS type, SUM(num*price) FROM order_item oi JOIN goods g ON oi.goods_idg.goods_id;六、注意事项职场终极规范主表永远放左边只用 LEFT JOIN右表条件放 ON不要放 WHERE** 禁止 SELECT ***只查需要字段关联字段必须建索引user_id、order_id、goods_id大表用 EXISTS不用 IN非存在查询只用 NOT EXISTS联合查询默认 UNION ALL统计一对多数据必须用 COUNT (DISTINCT)判断 NULL 必须用 IS NULL / IS NOT NULL多层连接不要跳表逐级 ON 关联七、核心总结全文最精华连接内连接取交集左连接保主表企业 90% 用 LEFT JOIN子查询标量单值、列表用 IN、存在用 EXISTS优化大表 EXISTS、非存在 NOT EXISTS、联合 UNION ALL避坑笛卡尔积、NULL、NOT IN、跳表连接能力三五表链式连接 子查询 统计 企业中高级 SQL 水平一句话通关口诀左连接为主表全留子查询 EXISTS 最优联合用 ALL 速度够NULL 与笛卡尔积要躲多表逐级不跳走职场 SQL 不用愁八、下一步学习预告从下一篇开始我们进入企业进阶刚需模块事务 ACID事务隔离级别窗口函数面试必考CTE 公用表表达式存储过程、触发器索引优化、EXPLAIN