MySQL - UNION vs JOIN
MySQL - UNION 与 JOIN 的对比
Section titled “MySQL - UNION 与 JOIN 的对比”在关系型数据库中,数据通常分散在多个表中。为了获取完整的信息,您需要组合这些数据。MySQL 提供了两个主要工具来实现这一点:UNION 和 JOIN。尽管两者都用于组合数据,但它们以根本不同的方式和出于不同的目的进行。
根本区别:拓宽数据 vs. 增长数据
Section titled “根本区别:拓宽数据 vs. 增长数据”理解它们之间区别的最简单方法是类比:
JOIN从其他表添加列。 它通过在其他表中查找相关数据并将其添加为新列,使您的结果集变得更宽。可以想象成在第二个电子表格中查找信息,并将其添加到第一个电子表格中匹配行的旁边。UNION从其他查询添加行。 它通过将一个查询的结果堆叠在另一个查询之上,使您的结果集变得更长。可以想象成从第二个电子表格中复制行,并将其粘贴到第一个电子表格的底部。
UNION 详解:组合行
Section titled “UNION 详解:组合行”UNION 运算符组合两个或多个 SELECT 语句的结果集。它有两条严格的规则:
- 在
UNION中的每个SELECT语句必须具有相同数量的列。 - 列的数据类型也必须相似,并且顺序相同。
默认情况下,UNION 会从最终结果集中移除重复行。如果您想包含所有行,包括重复项,请使用 UNION ALL,它也更快,因为它不需要检查重复项。
示例:组合活跃用户和已归档用户
Section titled “示例:组合活跃用户和已归档用户”假设您有两个结构相似的表:active_users(活跃用户)和 archived_users(已归档用户)。要获取所有用户电子邮件的单一列表,您将使用 UNION。
-- 表:active_users-- +----+------------------+-- | id | email |-- +----+------------------+-- | 1 | alice@example.com|-- | 2 | bob@example.com |-- +----+------------------+
-- 表:archived_users-- +---------+-------------------+-- | user_id | user_email |-- +---------+-------------------+-- | 101 | charlie@example.com |-- | 2 | bob@example.com |-- +---------+-------------------+
-- UNION 查询:SELECT email FROM active_usersUNIONSELECT user_email FROM archived_users;SELECT 列表中的列名可以不同(email vs. user_email),但它们的数量(一个)和数据类型(VARCHAR)必须兼容。最终结果将只有一列,并且重复的 ‘bob@example.com’ 将被移除。
| alice@example.com |
| bob@example.com |
| charlie@example.com |
JOIN 详解:组合列
Section titled “JOIN 详解:组合列”一个 JOIN 子句用于根据两个或多个表之间的相关列来组合它们的行。最常见的类型是 INNER JOIN,它返回在两个表中都有匹配值的记录。
示例:组合客户和订单
Section titled “示例:组合客户和订单”这是经典的用例。您有一个 customers 表和一个 orders 表。要查看哪个客户下了哪个订单,您需要通过它们的公共字段(customers 表中的 id 和 orders 表中的 customer_id)将它们连接起来。
-- 表:customers-- +----+--------+-- | id | name |-- +----+--------+-- | 1 | Alice |-- | 2 | Bob |-- +----+--------+
-- 表:orders-- +----------+-------------+--------------+-- | order_id | customer_id | product |-- +----------+-------------+--------------+-- | 101 | 2 | Laptop |-- | 102 | 1 | Mouse |-- | 103 | 2 | Keyboard |-- +----------+-------------+--------------+
-- JOIN 查询:SELECT c.name, o.productFROM customers AS cINNER JOIN orders AS o ON c.id = o.customer_id;结果结合了来自两个表的列,创建了一个更宽、信息更丰富的数据集。
| name | product |
|---|---|
| Bob | Laptop |
| Alice | Mouse |
| Bob | Keyboard |
关键区别总结
Section titled “关键区别总结”| 方面 | UNION | JOIN |
|---|---|---|
| 目的 | 将两个或多个结果集中的行组合成一个单一集合。 | 根据相关键组合来自两个或多个表的列。 |
| 数据方向 | 垂直追加数据(使结果变长)。 | 水平追加数据(使结果变宽)。 |
| 规则 | 要求相同数量的列和兼容的数据类型。 | 需要一个定义关系的连接条件(例如 ON 子句)。 |
| 重复项处理 | 默认情况下,UNION 会移除重复项。UNION ALL 允许重复项。 | 根据连接条件返回所有匹配的行;重复项不会被固有地移除。 |
| 结果列 | 使用第一个 SELECT 语句中的列名。 | 结果集包含所有连接表中的列。 |
何时使用哪一个
Section titled “何时使用哪一个”- 何时使用
UNION: 当您想组合来自不同表或查询的类似事物的列表时。例如,从customers、suppliers和employees表中获取所有联系电话号码的列表。 - 何时使用
JOIN: 当您想通过添加其他表中的相关信息来丰富数据时。例如,查找购买了特定产品(orders表)的客户姓名(customers表)。