在SQL查询场景中,Select语句用于从数据库中检索数据,而join和union是扩展Select查询能力的重要关键字,二者分别解决不同的数据整合需求,适用场景存在明显差异。

join的用法
join用于将两个或多个表的行根据关联条件进行组合,核心作用是实现多表关联查询,常见类型包括内连接、左连接、右连接等。
内连接 inner join
内连接返回两个表中满足关联条件的匹配行,不匹配的行会被过滤掉。
-- 查询用户表和用户订单表中匹配的用户及订单信息 SELECT u.user_id, u.user_name, o.order_id, o.order_amount FROM user u INNER JOIN order_table o ON u.user_id = o.user_id;
左连接 left join
左连接返回左表的所有行,即使右表中没有匹配的行,右表不匹配的字段会显示为null。
-- 查询所有用户及其订单信息,没有订单的用户订单字段显示为null SELECT u.user_id, u.user_name, o.order_id, o.order_amount FROM user u LEFT JOIN order_table o ON u.user_id = o.user_id;
右连接 right join
右连接返回右表的所有行,左表不匹配的字段显示为null,用法和左连接类似,只是主表顺序相反。
-- 查询所有订单及其对应的用户信息,没有对应用户信息的订单用户字段显示为null SELECT u.user_id, u.user_name, o.order_id, o.order_amount FROM user u RIGHT JOIN order_table o ON u.user_id = o.user_id;
union的用法
union用于合并两个或多个Select语句的结果集,要求参与合并的Select语句返回的列数相同,且对应列的数据类型兼容。
union去重合并
union默认会对合并后的结果集进行去重,重复的行只会保留一条。
-- 查询用户表中来自北京和上海的所有用户,去重重复记录 SELECT user_id, user_name, city FROM user WHERE city = '北京' UNION SELECT user_id, user_name, city FROM user WHERE city = '上海';
union all保留重复
union all不会去重,会保留所有Select语句返回的所有行,执行效率比union更高。
-- 查询用户表中来自北京和上海的所有用户,保留重复记录 SELECT user_id, user_name, city FROM user WHERE city = '北京' UNION ALL SELECT user_id, user_name, city FROM user WHERE city = '上海';
join和union的核心区别
二者的核心差异主要体现在以下几个维度:
- 作用对象不同:join是对表的行进行横向扩展,合并后列数是多个表的列数之和;union是对Select结果集的行进行纵向扩展,合并后列数和单个Select语句的列数一致。
- 数据匹配逻辑不同:join依赖关联条件匹配行,不匹配的行根据连接类型决定是否保留;union没有关联条件,只要求结果集结构兼容,直接拼接行。
- 适用场景不同:需要获取多表关联后的完整字段信息时使用join;需要合并多个结构相同的查询结果时使用union。
| 对比维度 | join | union |
|---|---|---|
| 数据扩展方向 | 横向扩展列 | 纵向扩展行 |
| 是否需要关联条件 | 需要 | 不需要 |
| 结果集列数 | 多个表的列数之和 | 单个Select语句的列数 |
| 典型使用场景 | 多表关联查询获取完整信息 | 多个同结构查询结果合并 |
使用示例注意事项
使用join时需要注意关联条件的准确性,避免出现笛卡尔积导致结果集异常膨胀。使用union时需要保证每个Select语句返回的列数、列顺序、数据类型一致,否则会执行报错。如果不需要去重,优先使用union all,可以提升查询性能。
-- 错误示例:union合并的两个Select列数不同,会报错 SELECT user_id, user_name FROM user UNION SELECT user_id FROM user; -- 正确示例:调整列数一致后再合并 SELECT user_id, user_name FROM user UNION SELECT user_id, NULL AS user_name FROM user;