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 与 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, '爱丽丝', '人力资源'),
(2, '鲍勃', 'IT'),
(3, '查理', '财务');

INSERT INTO former_employees VALUES
(4, '大卫', '市场营销'),
(5, '夏娃', 'IT'),
(2, '鲍勃', 'IT');  -- 鲍勃曾经在这里工作,离开后又回来了

-- 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 查询将只显示鲍勃一次,而 UNION ALL 将显示鲍勃两次。

示例 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