SELECT: SETOP

说明

集合操作

语法

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;