集合操作(UNION / INTERSECT / EXCEPT)
功能描述
集合操作用于将多个 SELECT 查询的结果合并为一个结果集。Lakehouse 支持以下集合操作:
| 操作 | 说明 |
|---|
| UNION | 返回两个查询结果的并集(去重) |
| UNION ALL | 返回两个查询结果的并集(保留重复行) |
| INTERSECT | 返回两个查询结果的交集(去重) |
| INTERSECT ALL | 返回两个查询结果的交集(保留重复行) |
| EXCEPT | 返回在第一个查询结果中但不在第二个中的行(去重) |
| EXCEPT ALL | 返回在第一个查询结果中但不在第二个中的行(保留重复行) |
| MINUS | EXCEPT 的同义词 |
语法
select_statement UNION [ALL | DISTINCT] select_statement
select_statement INTERSECT [ALL | DISTINCT] select_statement
select_statement EXCEPT [ALL | DISTINCT] select_statement
select_statement MINUS [ALL | DISTINCT] select_statement
- 不指定 ALL 或 DISTINCT 时,默认为 DISTINCT(去重)。
- 多个集合操作可以链式使用,从左到右依次计算。
- INTERSECT 的优先级高于 UNION 和 EXCEPT。即
A UNION B INTERSECT C 等价于 A UNION (B INTERSECT C)。
- ORDER BY 和 LIMIT 子句应用于整个结果集,需写在最后一个 SELECT 之后。
使用要求
- 所有参与集合操作的 SELECT 语句必须返回相同数量的列。
- 对应位置的列必须具有兼容的数据类型。
- 结果集的列名取自第一个 SELECT 语句。
使用示例
UNION / UNION ALL
-- UNION:去重合并
SELECT 1 AS id, 'a' AS name
UNION
SELECT 1, 'a';
-- 结果:1 行 (1, 'a')
-- UNION ALL:保留重复行
SELECT 1 AS id, 'a' AS name
UNION ALL
SELECT 1, 'a';
-- 结果:2 行 (1, 'a') 和 (1, 'a')
INTERSECT
-- 取两个结果集的交集
SELECT * FROM VALUES (1), (2), (3) AS t1(id)
INTERSECT
SELECT * FROM VALUES (2), (3), (4) AS t2(id);
-- 结果:2, 3
EXCEPT / MINUS
-- 取差集:在第一个结果中但不在第二个中
SELECT * FROM VALUES (1), (2), (3) AS t1(id)
EXCEPT
SELECT * FROM VALUES (2), (3), (4) AS t2(id);
-- 结果:1
-- MINUS 与 EXCEPT 等价
SELECT * FROM VALUES (1), (2), (3) AS t1(id)
MINUS
SELECT * FROM VALUES (2), (3), (4) AS t2(id);
-- 结果:1
链式使用与 ORDER BY
SELECT * FROM VALUES (1), (2) AS t1(id)
UNION ALL
SELECT * FROM VALUES (2), (3) AS t2(id)
UNION ALL
SELECT * FROM VALUES (3), (4) AS t3(id)
ORDER BY id;
-- 结果:1, 2, 2, 3, 3, 4
注意事项
- UNION(不带 ALL)会对结果去重,性能开销比 UNION ALL 大。如果确定不需要去重,建议使用 UNION ALL。
- 子查询中使用 ORDER BY 或 LIMIT 时,需要用括号包裹。
- MINUS 是 EXCEPT 的别名,行为完全一致。