UNION
本课属于 Coddy SQL 学习旅程的“基础知识”单元。第 48 课,共 72 课。
联合与连接不同。连接 使用条件来组合表,而联合 只是将两张表上下拼接。要使用 UNION,我们会这样写:
SELECT col1, col2, ... FROM table1
UNION
SELECT col1, col2, ... FROM table2两个 SELECT 都必须遵守以下规则:
- 字段数量必须相等
- 顺序很重要
- 相同位置的列应包含相同类型的数据(SQLite 不会检查它们的类型)
例如,假设我们有以下表:
germany_people
| id | name |
| 1 | Lena |
| 2 | Leonie |
england_people
| id | name |
| 1 | George |
| 2 | Lena |
问题:我们想把所有已有的名字合并成一个大表。
SELECT name from germany_people
UNION
SELECT name from england_people结果:
| name |
| Lena |
| Leonie |
| George |
UNION 只返回不重复的值,而 UNION ALL 会原样返回所有记录:
SELECT name from germany_people
UNION ALL
SELECT name from england_people结果:
| 名称 |
| Lena |
| Leonie |
| George |
| Lena |
你还可以将 UNION ALL 与聚合函数、GROUP BY 和 ORDER BY 结合起来,汇总多个表中的数据。关键是将 UNION ALL 放在子查询中,然后在此基础上进行分组和排序。
例如,假设我们想统计两个表中每个名称出现的次数:
SELECT name, COUNT(*) AS total_count
FROM (
SELECT name FROM germany_people
UNION ALL
SELECT name FROM england_people
) AS combined
GROUP BY name
ORDER BY total_count DESC结果:
| 姓名 | total_count |
| Lena | 2 |
| Leonie | 1 |
| George | 1 |
这里使用 UNION ALL(而不是 UNION),这样像 Lena 这样的重复项就会保留下来。否则,它们会在计数前被删除。子查询合并所有行,然后用 GROUP BY + COUNT 对它们进行汇总。ORDER BY 对最终结果进行排序。
挑战
简单可用的表和列:
sales_2009:product_id、quantity_soldsales_2010:product_id、quantity_soldsales_2011:product_id、quantity_sold
共有 3 个销售表。
计算所有表中每种产品的销售总量。
结果应包含 product_id 和销售总量。
将此列命名为 total_sales。
按销售总量降序排列结果。
亲手试试
-- 将这三个表合并成一个结果,保留所有行
SELECT product_id, ____ AS total_sales
FROM (
SELECT * FROM sales_2009
____
SELECT * FROM sales_2010
____
SELECT * FROM sales_2011
)
-- 每个产品占一行,按总量从大到小排列
GROUP BY ____
ORDER BY ____ DESC;这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: SQL 在线编辑器