SELECT: SETOP¶
说明¶
集合操作
参数¶
select_stmt
该查询语句,与普通查询语句的唯一区别在于:不能使用FOR UPDATE子句;若该查询语句没有用括号括起,则不能包含ORDER BY和LIMIT子句。
注解
SETOP子句将左右的结果进行集合操作。左右子查询可以是任意的SELECT语句(在右子查询之后可以使用这些子句,但此时这些子句是对整个集合操作的结果起作用)。
进行集合操作的两个子查询的结果中要求拥有相同数目的字段,并且每个对应的字段必须拥有兼容的数据类型。
集合操作可以是UNION, INTERSECT, EXCEPT或MINUS。在缺省情况下,集合操作将消除结果中的重复行,用户可以使用ALL关键字指定保留结果中的重复行。各种集合操作的含义如下:
UNION操作的结果为左右两个子查询结果的并集,同时消除重复;UNION ALL操作的结果为左右两个子查询结果的并,不消除重复。INTERSECT操作的结果为左右两个子查询的交集,同时消除重复;INTERSECT ALL操作的结果为左右两个子查询结果的交集,不消除重复,即若元组A在左右子查询中分别出现M次和N次,则INTERSECT ALL操作的结果中将包含min(M, N)个A元组。EXCEPT/MINUS操作的结果为左右两个子查询结果的差,同时消除重复;EXCEPT/MINUS ALL操作的结果为左右两个子查询结果的差,不消除重复,即若元组A在左右子查询中分别出现M次和N次,则EXCEPT/MINUS ALL操作的结果中将包含M-N个A元组(若M<=N,则结果中将不包含A);
Union/intersect/except/minus这些集合操作中的子集合不能是select for update语句。如以下语句是非法的:
select column1,column2 from test_tab_1 for update of test_tab_1 union all select column1,column2 from test_tab_2;
三个集合操作的优先级不同,UNION和EXCEPT/MINUS的优先级相同,INTERSECT的优先级比它们俩都高。即A UNION B INTERSECT C相当于A UNION (B INTERSECT C)。
示例¶
示例1: 集合操作
-- 清理环境
DROP TABLE tab1 CASCADE;
-- 创建表并插入数据
CREATE TABLE tab1 (a1 INT, b1 INT);
INSERT INTO tab1 VALUES(1, 10);
INSERT INTO tab1 VALUES(2, 20);
INSERT INTO tab1 VALUES(2, 20);
INSERT INTO tab1 VALUES(3, 30);
INSERT INTO tab1 VALUES(4, 40);
INSERT INTO tab1 VALUES(5, 50);
INSERT INTO tab1 VALUES(5, 50);
SELECT * FROM tab1 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
1 |10 |
--------------------------
2 |20 |
--------------------------
2 |20 |
--------------------------
3 |30 |
--------------------------
4 |40 |
--------------------------
5 |50 |
--------------------------
5 |50 |
总数目:7
CREATE TABLE tab2 (a2 INT, b2 INT);
INSERT INTO tab2 VALUES(1, 10);
INSERT INTO tab2 VALUES(3, 30);
INSERT INTO tab2 VALUES(5, 50);
INSERT INTO tab2 VALUES(7, 70);
INSERT INTO tab2 VALUES(7, 70);
INSERT INTO tab2 VALUES(9, 90);
SELECT * FROM tab2 ORDER BY 1, 2;
A2(int) |B2(int) |
--------------------------
1 |10 |
--------------------------
3 |30 |
--------------------------
5 |50 |
--------------------------
7 |70 |
--------------------------
7 |70 |
--------------------------
9 |90 |
总数目:6
-- UNION
SELECT * FROM tab1 UNION SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
1 |10 |
--------------------------
2 |20 |
--------------------------
3 |30 |
--------------------------
4 |40 |
--------------------------
5 |50 |
--------------------------
7 |70 |
--------------------------
9 |90 |
总数目:7
-- UNION ALL
SELECT * FROM tab1 UNION ALL SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
1 |10 |
--------------------------
1 |10 |
--------------------------
2 |20 |
--------------------------
2 |20 |
--------------------------
3 |30 |
--------------------------
3 |30 |
--------------------------
4 |40 |
--------------------------
5 |50 |
--------------------------
5 |50 |
--------------------------
5 |50 |
--------------------------
7 |70 |
--------------------------
7 |70 |
--------------------------
9 |90 |
总数目:13
-- INTERSECT
SELECT * FROM tab1 INTERSECT SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
1 |10 |
--------------------------
3 |30 |
--------------------------
5 |50 |
总数目:3
-- INTERSECT ALL
SELECT * FROM tab1 INTERSECT ALL SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
1 |10 |
--------------------------
3 |30 |
--------------------------
5 |50 |
总数目:3
-- EXCEPT
SELECT * FROM tab1 EXCEPT SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
2 |20 |
--------------------------
4 |40 |
总数目:2
-- EXCEPT ALL
SELECT * FROM tab1 EXCEPT ALL SELECT * FROM tab2 ORDER BY 1, 2;
A1(int) |B1(int) |
--------------------------
2 |20 |
--------------------------
2 |20 |
--------------------------
4 |40 |
--------------------------
5 |50 |
总数目:4
-- 删除表
DROP TABLE tab1;