
# SetOp
#### 算子说明
SetOp算子用于将两个或多个查询结果合并成一个结果集。SetOp算子包括INTERSECT和EXCEPT。
#### 典型场景
- INTERSECT：返回两个查询结果的交集，即两个结果集中都存在的行。
- INTERSECT ALL：返回两个查询结果的交集，包括重复的行。
- EXCEPT：返回第一个查询结果中存在，但第二个查询结果中不存在的行。
- EXCEPT ALL：返回第一个查询结果中存在，但第二个查询结果中不存在的行，包括重复的行。
 
#### 示例
**示例1：**INTERSECT。
```
--数据准备 
gaussdb=# DROP TABLE IF EXISTS t;
gaussdb=# CREATE TABLE t(a int, b int, c int); 
CREATE TABLE 
gaussdb=# INSERT INTO t VALUES(generate_series(1, 10), generate_series(601, 610), generate_series(901, 910)); 
INSERT 0 10
--执行结果。 
gaussdb=# EXPLAIN SELECT * FROM t INTERSECT SELECT * FROM t; 
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=27.94..28.61 rows=21 width=12)
   Node/s: All datanodes
   ->  SetOp Intersect  (cost=27.13..27.39 rows=21 width=12)
         ->  Sort  (cost=27.13..27.20 rows=42 width=12)
               Sort Key: "*SELECT* 1".a, "*SELECT* 1".b, "*SELECT* 1".c
               ->  Append  (cost=0.00..26.52 rows=42 width=12)
                     ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
                     ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
(10 rows)
```
上述示例中，SetOp算子输出信息如下所示。
| 信息名称      | 含义                                              |
|:---|:---|
| SetOp     | 算子的名称。                                          |
| Intersect | 合并结果集的方式，示例中Intersect为返回两个查询结果的交集，即两个结果集中都存在的行。 |
   
**示例2：**INTERSECT ALL。
```
gaussdb=# EXPLAIN SELECT * FROM t INTERSECT ALL SELECT * FROM t; 
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=27.94..28.61 rows=21 width=12)
   Node/s: All datanodes
   ->  SetOp Intersect All  (cost=27.13..27.39 rows=21 width=12)
         ->  Sort  (cost=27.13..27.20 rows=42 width=12)
               Sort Key: "*SELECT* 1".a, "*SELECT* 1".b, "*SELECT* 1".c
               ->  Append  (cost=0.00..26.52 rows=42 width=12)
                     ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
                     ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
(10 rows)
```
上述示例中，SetOp算子输出信息如下所示。
| 信息名称          | 含义                                            |
|:---|:---|
| SetOp         | 算子的名称。                                        |
| Intersect All | 合并结果集的方式，示例中Intersect All为返回两个查询结果的交集，包括重复的行。 |
   
**示例3：**EXCEPT。
```
gaussdb=# EXPLAIN SELECT * FROM t EXCEPT SELECT * FROM t; 
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=27.94..28.61 rows=21 width=12)
   Node/s: All datanodes
   ->  SetOp Except  (cost=27.13..27.39 rows=21 width=12)
         ->  Sort  (cost=27.13..27.20 rows=42 width=12)
               Sort Key: "*SELECT* 1".a, "*SELECT* 1".b, "*SELECT* 1".c
               ->  Append  (cost=0.00..26.52 rows=42 width=12)
                     ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
                     ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
(10 rows)
```
上述示例中，SetOp算子输出信息如下所示。
| 信息名称   | 含义                                              |
|:---|:---|
| SetOp  | 算子的名称。                                          |
| Except | 合并结果集的方式，示例中Except为返回第一个查询结果中存在，但第二个查询结果中不存在的行。 |
   
示例4：EXCEPT ALL。
```
gaussdb=# EXPLAIN SELECT * FROM t EXCEPT ALL SELECT * FROM t; 
                                         QUERY PLAN
--------------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=27.94..28.61 rows=21 width=12)
   Node/s: All datanodes
   ->  SetOp Except All  (cost=27.13..27.39 rows=21 width=12)
         ->  Sort  (cost=27.13..27.20 rows=42 width=12)
               Sort Key: "*SELECT* 1".a, "*SELECT* 1".b, "*SELECT* 1".c
               ->  Append  (cost=0.00..26.52 rows=42 width=12)
                     ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
                     ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..13.26 rows=21 width=12)
                           ->  Seq Scan on t  (cost=0.00..13.13 rows=20 width=12)
(10 rows)
--删除。
gaussdb=# DROP TABLE t;
```
上述示例中，SetOp算子输出信息如下所示。
| 信息名称       | 含义                                                         |
|:---|:---|
| SetOp      | 算子的名称。                                                     |
| Except All | 合并结果集的方式，示例中Except All为返回第一个查询结果中存在，但第二个查询结果中不存在的行，包括重复的行。 |
   
