SQL - UNION 与 UNION ALL 的区别

你好,有抱负的SQL爱好者们!今天,我们将踏上一段激动人心的SQL世界之旅,特别关注两个强大的操作符:UNION 和 UNION ALL。作为你友好邻邦的计算机老师,我拥有多年的经验,在这里我将用清晰、幽默的方式,以及大量的现实世界示例来引导你了解这些概念。那么,让我们开始吧!

SQL - UNION vs UNION ALL

什么是 UNION?

定义与基本概念

UNION 就像一位大厨,将不同食谱的食材结合起来,创造出一道独特的菜肴。在SQL术语中,它是一个操作符,允许我们将两个或多个SELECT语句的结果集合并成单个结果集。

这里的基本语法如下:

SELECT column1, column2, ... FROM table1
UNION
SELECT column1, column2, ... FROM table2;

UNION 的关键特性

  1. 去重结果:UNION 会自动从最终结果集中移除重复的行。
  2. 列兼容性:SELECT 语句必须有相同数量的列,并且这些列应具有兼容的数据类型。
  3. 列的顺序:SELECT 语句中列的顺序很重要,因为它们会根据位置进行合并。

UNION 的实际应用

让我们想象我们有两个表:fruitsvegetables。我们想要创建一个包含所有农产品项的合并列表。

-- fruits 表
CREATE TABLE fruits (
id INT,
name VARCHAR(50),
color VARCHAR(20)
);

INSERT INTO fruits VALUES
(1, '苹果', '红色'),
(2, '香蕉', '黄色'),
(3, '橙子', '橙色');

-- vegetables 表
CREATE TABLE vegetables (
id INT,
name VARCHAR(50),
color VARCHAR(20)
);

INSERT INTO vegetables VALUES
(1, '胡萝卜', '橙色'),
(2, '西兰花', '绿色'),
(3, '番茄', '红色');

-- UNION 查询
SELECT name, color FROM fruits
UNION
SELECT name, color FROM vegetables;

这个查询将返回以下结果:

name color
苹果 红色
香蕉 黄色
橙子 橙色
胡萝卜 橙色
西兰花 绿色
番茄 红色

注意到我们只有一个 '橙色' 条目,尽管它出现在两个表中。这就是 UNION 的魔力——它移除了重复项!

什么是 UNION ALL?

定义与基本概念

现在,让我们来见见 UNION 的热情表亲,UNION ALL。当 UNION 像一位仔细的大厨移除重复的食材时,UNION ALL 则像一位认为“越多越开心”的大厨!

语法与 UNION 类似:

SELECT column1, column2, ... FROM table1
UNION ALL
SELECT column1, column2, ... FROM table2;

UNION ALL 的关键特性

  1. 保留重复项:UNION ALL 会保留所有行,包括重复项。
  2. 性能更佳:因为它不需要移除重复项,所以 UNION ALL 通常比 UNION 更快。
  3. 列兼容性:与 UNION 相同,它要求相同数量的列,并且列的数据类型要兼容。

UNION ALL 的实际应用

再次使用我们的 fruitsvegetables 表:

SELECT name, color FROM fruits
UNION ALL
SELECT name, color FROM vegetables;

这个查询将产生以下结果:

name color
苹果 红色
香蕉 黄色
橙子 橙色
胡萝卜 橙色
西兰花 绿色
番茄 红色

注意到我们现在有两个 '橙色' 条目——一个来自水果,一个来自蔬菜。UNION ALL 保留了所有行,包括重复项!

UNION vs UNION ALL:正面比较

为了真正理解差异,让我们将它们并排放在一起比较:

特性 UNION UNION ALL
重复处理 移除重复项 保留所有重复项
性能 较慢(由于去重) 更快
结果集大小 可能更小 可能更大
用例 当需要唯一结果时 当需要所有结果,包括重复项时

何时使用 UNION

当你需要从多个查询中合并结果,并确保结果集中的每一行都是唯一的时,使用 UNION。它非常适合以下场景:

  1. 合并不同地区的客户列表,确保没有重复。
  2. 合并不同供应商的产品目录,移除重复的商品。

何时使用 UNION ALL

在以下情况下选择 UNION ALL:

  1. 你知道数据集中没有重复项。
  2. 你特别需要保留所有行,包括重复项。
  3. 性能是优先考虑的,并且你正在处理大量数据。

实际示例

让我们深入研究一些现实世界的场景来巩固我们的理解。

示例 1:员工名录

想象我们有两个表:current_employeesformer_employees。我们想要创建一个全面的名录。

-- 创建并填充表
CREATE TABLE current_employees (id INT, name VARCHAR(50), department VARCHAR(50));
CREATE TABLE former_employees (id INT, name VARCHAR(50), department VARCHAR(50));

INSERT INTO current_employees VALUES
(1, 'Alice', '人力资源'),
(2, 'Bob', 'IT'),
(3, 'Charlie', '财务');

INSERT INTO former_employees VALUES
(4, 'David', '市场'),
(5, 'Eve', 'IT'),
(2, 'Bob', 'IT');  -- Bob 曾经在这里工作过,离开后又回来了

-- UNION 查询
SELECT name, department FROM current_employees
UNION
SELECT name, department FROM former_employees;

-- UNION ALL 查询
SELECT name, department FROM current_employees
UNION ALL
SELECT name, department FROM former_employees;

UNION 查询只会显示 Bob 一次,而 UNION ALL 会显示 Bob 两次。

示例 2:销售报告

让我们创建一个合并在线和店内销售的销售报告。

-- 创建并填充表
CREATE TABLE online_sales (product VARCHAR(50), amount DECIMAL(10,2));
CREATE TABLE store_sales (product VARCHAR(50), amount DECIMAL(10,2));

INSERT INTO online_sales VALUES
('笔记本电脑', 1200.00),
('手机', 800.00),
('平板电脑', 500.00);

INSERT INTO store_sales VALUES
('笔记本电脑', 1100.00),
('手机', 750.00),
('耳机', 200.00);

-- 总共销售的独特产品(UNION)
SELECT product FROM online_sales
UNION
SELECT product FROM store_sales;

-- 所有销售记录(UNION ALL)
SELECT '在线' AS source, product, amount FROM online_sales
UNION ALL
SELECT '门店' AS source, product, amount FROM store_sales;

UNION 查询给我们提供了跨渠道销售的唯一产品列表,而 UNION ALL 提供了所有销售交易的完整列表。

结论

亲爱的学生们,以上就是我们的旅程!我们一起穿越了 UNION 和 UNION ALL 的领域,探索了它们的相似之处、不同之处以及现实世界的应用。记住,当你需要唯一、去重的结果时,UNION 是你的首选;而当你需要所有数据,包括重复项时,UNION ALL 是你的快速朋友。

在你继续你的SQL冒险之旅时,你会找到无数使用这些强大工具的机会。就像烹饪一样,知道何时使用每种“食材”(或者在我们的例子中,是操作符)是创造完美查询配方关键。

继续练习,保持好奇心,不要害怕尝试这些概念。在你意识到之前,你将像专业人士一样 UNION 和 UNION ALL。愉快的查询!

Credits: Image by storyset