马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
🍋🍋大数据学习🍋🍋
🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。
💖假如觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞
在 SQL 口试中,JOIN 是高频考点,口试官通常会考察对不同连接类型的明白、应用场景、性能优化以及关联条件的逻辑。
一、底子概念:JOIN 的类型与区别
1. 常见 JOIN 类型对比
连接类型英文全称核心逻辑效果行数特点INNER JOIN内连接仅返回两张表中满足关联条件的行(交集)大概少于或等于原表行数LEFT JOIN左外连接返回左表全部行,右表匹配行,无匹配时右表字段为 NULL至少等于左表行数RIGHT JOIN右外连接返回右表全部行,左表匹配行,无匹配时左表字段为 NULL至少等于右表行数FULL JOIN全外连接(全连接)返回左表和右表全部行,无匹配时对应字段为 NULL(等价于 LEFT+RIGHT)大概多于两表行数之和(去重前)CROSS JOIN交叉连接(笛卡尔积)不使用关联条件,返回两表全部行的组合(左表行数 × 右表行数)效果集最大,需制止滥用2. 口试必问:LEFT JOIN 和 INNER JOIN 的区别?
答案要点:
- 效果集差异:LEFT JOIN 包含左表全部行,无匹配时右表字段为 NULL;INNER JOIN 仅返回匹配行。
- 应用场景:
- LEFT JOIN 用于统计左表数据的关联情况(如 “查询全部用户及其订单”);
- INNER JOIN 用于筛选两表均存在的数据(如 “查询同时有用户和订单的记载”)。
二、口试高频题目与陷阱
1. 关联条件(ON vs WHERE)
题目:LEFT JOIN 中,条件写在 ON 和 WHERE 有什么区别?
示例:- -- 场景:左表 A(用户表),右表 B(订单表),查询用户及其订单,且订单金额 > 100
- -- 写法 1:条件在 ON 中
- SELECT A.name, B.amount
- FROM A
- LEFT JOIN B ON A.id = B.user_id AND B.amount > 100;
- -- 写法 2:条件在 WHERE 中
- SELECT A.name, B.amount
- FROM A
- LEFT JOIN B ON A.id = B.user_id
- WHERE B.amount > 100;
复制代码
- ON 是连接条件:在天生暂时表时过滤右表数据,不满足条件的右表行仍会以 NULL 形式保存在效果中(左表行保存)。
- 例 1 效果:全部用户都会出现,右表字段 amount 为 NULL 或满足金额 > 100 的值。
- WHERE 是效果过滤条件:先完成连接(保存左表全部行),再过滤效果中不满足条件的行(包罗左表行)。
- 例 2 效果:仅保存右表金额 > 100 的用户(等价于 INNER JOIN),左表无订单或订单金额 ≤ 100 的用户会被过滤。
陷阱提示:LEFT JOIN 中若条件涉及右表字段,写在 WHERE 会导致左表部分行被过滤,需根据需求选择。
2. 多表连接的逻辑顺序
题目:写出三表连接(A LEFT JOIN B ON ..., A INNER JOIN C ON ...)的实验顺序。
答案要点:
SQL 实验顺序(简化版):
- FROM A:确定主表。
- LEFT JOIN B ON ...:将 B 与 A 连接,保存 A 全部行。
- INNER JOIN C ON ...:将效果与 C 连接,仅保存 C 中匹配的行。
关键点:多表连接时,先处理 ON 条件,再按连接类型合并效果,最后处理 WHERE/HAVING 等后续条件。
3. 自连接(Self JOIN)的应用
题目:怎样用自连接查询 “员工及其上级向导”?
- SELECT e.emp_name AS 员工, m.emp_name AS 上级领导
- FROM employees e
- LEFT JOIN employees m ON e.manager_id = m.emp_id;
复制代码 要点:自连接需为表取别名(如 e 和 m),区分主表和关联表。
三、经典口试例题
例题 1:统计用户订单情况(LEFT JOIN + 聚合函数)
需求:查询全部用户(包罗无订单用户),统计其订单总数和总金额。
表结构:
- 用户表 users:user_id(主键)、username
- 订单表 orders:order_id、user_id(外键)、amoun
- SELECT
- u.user_id,
- u.username,
- COUNT(o.order_id) AS 订单总数,
- SUM(o.amount) AS 总金额
- FROM users u
- LEFT JOIN orders o ON u.user_id = o.user_id
- GROUP BY u.user_id, u.username;
复制代码 关键点:
- 聚合函数(如 COUNT)对 NULL 行(无订单用户)会返回 0 或 NULL?
- COUNT(o.order_id) 对 NULL 行返回 0(因为 order_id 为 NULL 时不计入统计);
- 若需强制返回 0,可使用 COALESCE(SUM(o.amount), 0)。
例题 2:找出重复数据(INNER JOIN + 自连接)
需求:在 students 表中找出姓名和年龄都重复的学生。
表结构:student_id、name、age
SQL 示例:- SELECT s1.name, s1.age
- FROM students s1
- INNER JOIN students s2 ON s1.name = s2.name AND s1.age = s2.age AND s1.student_id > s2.student_id
- GROUP BY s1.name, s1.age;
复制代码 要点:
- 自连接通过 student_id > student_id 制止同一行匹配自身;
- 效果可通过 DISTINCT 去重。
例题 3:多表连接关联条件优先级(陷阱题)
需求:查询用户及其订单和商品信息,要求订单时间在 2023 年,且商品类别为 “电子产品”。
表结构:
- users:user_id
- orders:order_id、user_id、order_time
- order_items:order_id、item_id
- products:item_id、category
错误写法:
- SELECT u.user_id, o.order_id, p.item_id
- FROM users u
- LEFT JOIN orders o ON u.user_id = o.user_id
- LEFT JOIN order_items oi ON o.order_id = oi.order_id
- LEFT JOIN products p ON oi.item_id = p.item_id
- WHERE o.order_time >= '2023-01-01' AND p.category = '电子产品';
复制代码 题目:WHERE 条件中的 o.order_time 和 p.category 会过滤掉左表(users)的部分行,导致无订单或非电子产品的用户被排除,违背 LEFT JOIN 保存左表全部行的初志。
正确写法:- SELECT u.user_id, o.order_id, p.item_id
- FROM users u
- LEFT JOIN orders o ON u.user_id = o.user_id AND o.order_time >= '2023-01-01'
- LEFT JOIN order_items oi ON o.order_id = oi.order_id
- LEFT JOIN products p ON oi.item_id = p.item_id AND p.category = '电子产品';
复制代码 要点:将过滤条件移至 ON 中,确保左表(users)全部行保存,右表不满足条件的字段为 NULL。
四、性能优化:JOIN 的常见陷阱
1. 制止大表 CROSS JOIN
题目:CROSS JOIN 会天生笛卡尔积,导致效果集爆炸,严肃影响性能。
优化:
- 必须使用时,确保关联条件(ON)能大幅过滤数据;
- 优先用 INNER JOIN 或其他连接类型替换。
2. 索引优化
场景:JOIN 字段(如外键)未创建索引,导致全表扫描。
优化:
- 为连接条件中的字段(如 A.id = B.user_id 中的 user_id)创建索引;
- 注意:LEFT JOIN 中,索引应优先创建在右表(被驱动表)的连接字段上。
3. 减少 JOIN 表数量
题目:超过 3 张表的 JOIN 大概导致实验计划复杂,性能降落。
优化:
- 拆分为子查询或暂时表;
- 制止冗余关联(如重复连接同一表)。
|