集合运算

TiDB 支持三种集合运算:并集 (UNION),差集 (EXCEPT) 和交集 (INTERSECT)。最小的集合单位是一个 SELECT 语句。

并集 (UNION)

数学上,两个集合 A 和 B 的并集是含有所有属于 A 或属于 B 的元素。下面是一个 UNION 的例子:

1. select 1 union select 2;
2. +---+
3. | 1 |
4. +---+
5. | 2 |
6. | 1 |
7. +---+
8. 2 rows in set (0.00 sec)

TiDB 支持 UNION ALL 和 UNION DISTINCT 并集,两者区别在于 UNION DISTINCT 会对并集结果去重复,而 UNION ALL 不会。TiDB 中默认使用 UNION DISTINCT。

1. create table t1 (a int);
2. create table t2 (a int);
3. insert into t1 values (1),(2);
4. insert into t2 values (1),(3);

UNION DISTINCT与 UNION ALL 的结果分别如下:

1. select * from t1 union distinct select * from t2;
2. +---+
3. | a |
4. +---+
5. | 1 |
6. | 2 |
7. | 3 |
8. +---+
9. 3 rows in set (0.00 sec)

11. select * from t1 union all select * from t2;
12. +---+
13. | a |
14. +---+
15. | 1 |
16. | 2 |
17. | 1 |
18. | 3 |
19. +---+
20. 4 rows in set (0.00 sec)

差集 (EXCEPT)

若 A 和 B 是集合,则 A 与 B 的差集是由所有属于 A 但不属于 B 的元素组成的集合。

1. select * from t1 except select * from t2;
2. +---+
3. | a |
4. +---+
5. | 2 |
6. +---+
7. 1 rows in set (0.00 sec)

差集 (EXCEPT) 暂时不支持 EXCEPT ALL。

交集 (INTERSECT)

数学上,两个集合 A 和 B 的交集是含有所有既属于 A 又属于 B 的元素,而且没有其他元素的集合。

1. select * from t1 intersect select * from t2;
2. +---+
3. | a |
4. +---+
5. | 1 |
6. +---+
7. 1 rows in set (0.00 sec)

交集 (INTERSECT) 暂时不支持 INTERSECT ALL。交集 (INTERSECT) 的计算优先级大于差集 (EXCEPT) 和并集 (UNION)。

1. select * from t1 union all select * from t1 intersect select * from t2;
2. +---+
3. | a |
4. +---+
5. | 1 |
6. | 1 |
7. | 2 |
8. +---+
9. 3 rows in set (0.00 sec)

括号优先

TiDB 支持使用括号修改集合运算的优先级,如同四则运算中先计算括号部分,集合运算也先计算括号内的部分。

1. (select * from t1 union all select * from t1) intersect select * from t2;
2. +---+
3. | a |
4. +---+
5. | 1 |
6. +---+
7. 1 rows in set (0.00 sec)

与 Order By 和 Limit 结合

TiDB 支持单独为整个集合运算进行 ORDER BY 或者 LIMIT。

1. (select * from t1 union all select * from t1 intersect select * from t2) order by a limit 2;
2. +---+
3. | a |
4. +---+
5. | 1 |
6. | 1 |
7. +---+
8. 2 rows in set (0.00 sec)