更新时间:2025-05-29 GMT+08:00

SetOp

算子说明

SetOp算子用于将两个或多个查询结果合并成一个结果集。SetOp算子包括INTERSECT和EXCEPT。

典型场景

  • INTERSECT:返回两个查询结果的交集,即两个结果集中都存在的行。
  • INTERSECT ALL:返回两个查询结果的交集,包括重复的行。
  • EXCEPT:返回第一个查询结果中存在,但第二个查询结果中不存在的行。
  • EXCEPT ALL:返回第一个查询结果中存在,但第二个查询结果中不存在的行,包括重复的行。

示例

示例1:INTERSECT。

--数据准备。
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=# ANALYZE t;
ANALYZE
gaussdb=# SET enable_hashagg = on;
SET

--执行结果。 
gaussdb=# EXPLAIN SELECT * FROM t INTERSECT SELECT * FROM t; 
                                    QUERY PLAN                                     
---------------------------------------------------------------------------------- 
 HashSetOp Intersect  (cost=0.00..126.97 rows=217 width=12) 
   ->  Append  (cost=0.00..97.80 rows=3890 width=12) 
         ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
         ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
(6 rows)

上述示例中,SetOp算子输出信息如下所示。

信息名称

含义

SetOp

算子的名称。

Intersect

合并结果集的方式,示例中Intersect为返回两个查询结果的交集,即两个结果集中都存在的行。

示例2:INTERSECT ALL。

gaussdb=# EXPLAIN SELECT * FROM t INTERSECT ALL SELECT * FROM t; 
                                    QUERY PLAN                                     
---------------------------------------------------------------------------------- 
 HashSetOp Intersect All  (cost=0.00..126.97 rows=1945 width=12) 
   ->  Append  (cost=0.00..97.80 rows=3890 width=12) 
         ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
         ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
(6 rows)

上述示例中,SetOp算子输出信息如下所示。

信息名称

含义

SetOp

算子的名称。

Intersect All

合并结果集的方式,示例中Intersect All为返回两个查询结果的交集,包括重复的行。

示例3:EXCEPT。

gaussdb=# EXPLAIN SELECT * FROM t EXCEPT SELECT * FROM t; 
                                    QUERY PLAN                                     
---------------------------------------------------------------------------------- 
 HashSetOp Except  (cost=0.00..126.97 rows=217 width=12) 
   ->  Append  (cost=0.00..97.80 rows=3890 width=12) 
         ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
         ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
(6 rows) 

上述示例中,SetOp算子输出信息如下所示。

信息名称

含义

SetOp

算子的名称。

Except

合并结果集的方式,示例中Except为返回第一个查询结果中存在,但第二个查询结果中不存在的行。

示例4:EXCEPT ALL。

gaussdb=# EXPLAIN SELECT * FROM t EXCEPT ALL SELECT * FROM t; 
                                    QUERY PLAN                                     
---------------------------------------------------------------------------------- 
 HashSetOp Except All  (cost=0.00..126.97 rows=1945 width=12) 
   ->  Append  (cost=0.00..97.80 rows=3890 width=12) 
         ->  Subquery Scan on "*SELECT* 1"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
         ->  Subquery Scan on "*SELECT* 2"  (cost=0.00..48.90 rows=1945 width=12) 
               ->  Seq Scan on t  (cost=0.00..29.45 rows=1945 width=12) 
(6 rows) 

--删除。
gaussdb=# DROP TABLE t;

上述示例中,SetOp算子输出信息如下所示。

信息名称

含义

SetOp

算子的名称。

Except All

合并结果集的方式,示例中Except All为返回第一个查询结果中存在,但第二个查询结果中不存在的行,包括重复的行。