SQLite - 联合子句(UNIONS Clause)

你好,未来的数据库法师们!今天,我们将踏上一段激动人心的旅程,探索SQLite的世界,并了解神奇的联合子句(UNIONS clause)。作为你友好邻里的计算机老师,我会一步一步地引导你完成这次冒险。所以,拿起你的虚拟魔杖(键盘),让我们开始吧!

SQLite - UNIONS Clause

什么是联合(UNION)?

想象你有两个分别列出了你最喜欢的冰淇淋口味的列表——一个是去年夏天的,一个是今年夏天的。现在,如果你想要将这些列表合并成一个包含所有你喜欢口味的超级列表呢?在SQLite中,联合子句(UNION)基本上就是这样做的,不过是针对数据库表而不是冰淇淋口味!

在SQLite中,联合子句允许你合并两个或更多SELECT语句的结果集。这就像是在举办一个大型派对,不同的数据组可以在这里交流和形成一个更大的组。

基本语法

联合的基本语法如下:

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

让我们来分解一下:

  1. 我们有两个SELECT语句。
  2. 每个SELECT语句可以查询不同的表。
  3. 联合关键字(UNION)位于这些语句之间,起到桥梁的作用。

重要的规则

在我们进入示例之前,让我们回顾一些使用联合时的重要规则:

  1. 所有SELECT语句中的列数和顺序必须相同。
  2. 对应列的数据类型应该是兼容的。
  3. 默认情况下,联合会移除重复的行(稍后会介绍如何更改这一点)。

联合实战

让我们创建一些示例表,看看联合是如何工作的!

-- 创建并填充 'employees' 表
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT,
department TEXT
);

INSERT INTO employees (name, department) VALUES
('Alice', 'HR'),
('Bob', 'IT'),
('Charlie', 'Finance');

-- 创建并填充 'contractors' 表
CREATE TABLE contractors (
id INTEGER PRIMARY KEY,
name TEXT,
department TEXT
);

INSERT INTO contractors (name, department) VALUES
('David', 'Marketing'),
('Eve', 'IT'),
('Frank', 'HR');

现在,让我们使用联合来合并这些表:

SELECT name, department FROM employees
UNION
SELECT name, department FROM contractors;

这个查询将返回:

Alice    HR
Bob      IT
Charlie  Finance
David    Marketing
Eve      IT
Frank    HR

这里发生了什么?联合子句将两个表的结果合并在一起,给了我们一个包含所有员工(员工和承包商)的完整列表,没有重复。

去重魔法

你注意到有趣的事情了吗?尽管我们在HR部门有两个员工(Alice和Frank),他们两个都出现在了我们的结果中。这是因为联合默认会根据所有列的值自动移除重复行。

如果我们有两个表中的某个人有完全相同的名字和部门,联合只会显示一次。例如:

INSERT INTO contractors (name, department) VALUES ('Alice', 'HR');

SELECT name, department FROM employees
UNION
SELECT name, department FROM contractors;

这仍然会给我们之前相同的结果,不会有额外的'HR'部门的Alice。

联合 ALL 子句

有时,你可能希望保留所有行,即使是重复的。这时,联合ALL子句就派上用场了。这就像告诉数据库:“我希望这个派对上的每个人都在,即使他们有双胞胎!”

让我们修改之前的查询:

SELECT name, department FROM employees
UNION ALL
SELECT name, department FROM contractors;

现在我们得到:

Alice    HR
Bob      IT
Charlie  Finance
David    Marketing
Eve      IT
Frank    HR
Alice    HR

看到我们现在有两个HR部门的Alice了吗?联合ALL保留了所有行,不管是否有重复。

实际应用

联合和联合ALL不仅仅是为了好玩——它们在现实世界中有实际应用!以下是一些你可能使用它们的场景:

  1. 合并具有相似结构的多张表中的数据(就像我们的员工和承包商示例)。
  2. 创建跨越不同时间段或类别的报告。
  3. 合并来自不同数据库或数据源的数据。

让我们看一个更复杂的例子。想象我们经营一家书店,并希望看到所有的交易,无论是购买还是退货:

-- 创建并填充 'purchases' 表
CREATE TABLE purchases (
id INTEGER PRIMARY KEY,
book_title TEXT,
amount DECIMAL(10, 2),
transaction_date DATE
);

INSERT INTO purchases (book_title, amount, transaction_date) VALUES
('The Great Gatsby', 15.99, '2023-06-01'),
('To Kill a Mockingbird', 12.50, '2023-06-02'),
('1984', 10.99, '2023-06-03');

-- 创建并填充 'returns' 表
CREATE TABLE returns (
id INTEGER PRIMARY KEY,
book_title TEXT,
amount DECIMAL(10, 2),
transaction_date DATE
);

INSERT INTO returns (book_title, amount, transaction_date) VALUES
('The Great Gatsby', -15.99, '2023-06-05'),
('Pride and Prejudice', -14.99, '2023-06-06');

-- 合并购买和退货
SELECT book_title, amount, transaction_date, 'Purchase' as transaction_type
FROM purchases
UNION ALL
SELECT book_title, amount, transaction_date, 'Return' as transaction_type
FROM returns
ORDER BY transaction_date;

这个查询将给我们:

The Great Gatsby       15.99   2023-06-01  Purchase
To Kill a Mockingbird  12.50   2023-06-02  Purchase
1984                   10.99   2023-06-03  Purchase
The Great Gatsby      -15.99   2023-06-05  Return
Pride and Prejudice   -14.99   2023-06-06  Return

在这里,我们使用联合ALL合并了购买和退货,添加了一个列来区分交易类型,并按日期排序。

技巧和窍门

  1. 排序结果:你可以在联合查询的末尾添加一个ORDER BY子句来对合并后的结果进行排序。

  2. 过滤合并后的结果:在各自的SELECT语句中使用WHERE子句来过滤单个表,或者将联合查询包装在子查询中并在其上应用WHERE子句来过滤合并后的结果。

  3. 列别名:如果你的列在不同的表中有不同的名称,你可以使用别名来使它们匹配:

SELECT name AS person, department FROM employees
UNION
SELECT contractor_name AS person, dept AS department FROM contractors;
  1. 合并多于两个表:你不仅限于合并两个表——你可以链接多个联合或联合ALL子句来合并多个表。

常见方法

下面是一个总结SQLite中与联合相关的常见方法的表格:

方法 描述 示例
联合 合并两个或更多SELECT语句的结果并移除重复项 SELECT * FROM table1 UNION SELECT * FROM table2
联合ALL 合并两个或更多SELECT语句的结果并保留所有行,包括重复项 SELECT * FROM table1 UNION ALL SELECT * FROM table2
ORDER BY 与联合一起使用来对合并后的结果进行排序 (SELECT * FROM table1 UNION SELECT * FROM table2) ORDER BY column_name
WHERE 在单个SELECT语句中使用以过滤结果,然后再合并 SELECT * FROM table1 WHERE condition UNION SELECT * FROM table2 WHERE condition

就这样,伙计们!你已经通过掌握联合子句升级了你的SQLite技能。记住,熟能生巧,所以不要害怕在你自己的数据集上尝试这些查询。快乐查询,愿你的联合总是成功!

Credits: Image by storyset