UNION ALL 运算符
如果您使用 UNION ALL 运算符,则从两个查询返回所有符合条件的行,而不排除任何重复的行。(如果您使用 UNION 运算符而不带 ALL 关键字来组合两个查询,则从符合条件的行的组合的集合移除任何重复的行。也就是说,如果有多行,它们每一列包含的值均完全相同,那么只保留一行。)
下一示例使用 UNION ALL 来组合两个 SELECT 语句的结果,而不移除重复行。该查询返回在 2007 年第一季度与 2008 年第一季度期间接收的所有电话的列表。
SELECT customer_num, call_code FROM cust_calls
WHERE call_dtime BETWEEN
DATETIME (2007-1-1) YEAR TO DAY
AND DATETIME (2007-3-31) YEAR TO DAY
UNION ALL
SELECT customer_num, call_code FROM cust_calls
WHERE call_dtime BETWEEN
DATETIME (2008-1-1)YEAR TO DAY
AND DATETIME (2008-3-31) YEAR TO DAY;
如果想要从结果集移除重复行,请使用不带关键字 ALL 的 UNION 作为查询之间的集合运算符。在前一示例中,如果两个 SELECT 语句都返回了组合 101 B,则 UNION 运算符会导致该组合只罗列一次。(如果您想要移除每一 SELECT 语句中的重复行,则请紧接在 Projection 子句的 Select 列表之前使用 DISTINCT 或 UNIQUE 关键字,如同 允许重复 中描述的那样。)
对于指定仅带有 UNION 运算符的集合操作,ALL 关键字是有效的。如果 ALL 紧跟在 INTERSECT、MINUS 或 EXCEPT 集合运算符之后,这些集合运算符排除重复的部分,则数据库服务器发出错误。
要获取关于数据库服务器如何在有 NLCASE INSENSITIVE 属性的数据库中标识重复的 NCHAR 或 NVARCHAR 值的信息,请参阅主题 在区分大小写的数据库中的 NCHAR 和 NVARCHAR 表达式。
子查询中的 UNION
您可在 WHERE 子句、FROM 子句之内的 SELECT 语句的子查询中,以及在集合子查询中使用 UNION 和 UNION ALL 运算符。然而,在此 GBase 8s 版本中,在下列上下文中不支持包含 UNION 或 UNION ALL 的子查询:
在视图的定义中
在触发器的事件或 Action 子句中
使用 FOR UPDATE 子句或使用 Update 游标
有关集合子查询的信息,请参阅 集合子查询。关于 FOR UPDATE 子句的更多信息,请参阅 FOR UPDATE 子句。
特别地是,在本版本数据库中支持在分布式查询中包含 UNION 的子查询。
在组合的子查询中,数据库服务器只能在列的限定表引用的作用域中解析出列名。例如,下列查询返回错误:
SELECT * FROM t1 WHERE EXISTS
(SELECT a FROM t2
UNION
SELECT b FROM t3 WHERE t3.c IN
(SELECT t4.x FROM t4 WHERE t4.4 = t2.z));
在此,不可解析最内部的子查询 t2.z,因为 z 发生在表引用 t2 的引用范围之外。在最内部的子查询中,仅可解析属于 t4、t3 或 t1 的列引用。表引用的作用域通过子查询向下扩展,但不越过 UNION 运算符扩展到兄弟 SELECT 语句。
INTERSECT 运算符
当通过此集合运算符组合两个查询时,INTERSECT 计算通过为其运算对象的两个查询返回的行的交集。
INTERSECT 返回的行展现在左边和右边的 SELECT 语句的结果集中。INTERSECT 结果通常是不同的或唯一的行,因为 INTERSECT 消除任何重复的行。
请考虑下列示例,其中表 t1 有下列行:
create table t1 (col1 int);
insert into t1 values (1);
insert into t1 values (2);
insert into t1 values (2);
insert into t1 values (2);
insert into t1 values (3);
insert into t1 values (4);
insert into t1 values (4);
insert into t1 values (NULL);
insert into t1 values (NULL);
insert into t1 values (NULL);
在同一示例中,表 t2 有这些行:
create table t2 (col1 int);
insert into t2 values (1);
insert into t2 values (3);
insert into t2 values (4);
insert into t2 values (4);
insert into t2 values (NULL);
下列查询从 INTERSECT 操作对象的左边与右边的两个查询返回不同的行。在此要注意的重要问题是该结果有 NULL 值。因为当将表 t2 与表 t1 进行比较时,考虑到表 t2 中的 NULL 值是相等的,因此来自该交集的 NULL 值返回在组合的结果集中:
SELECT col1 FROM t1 INTERSECT SELECT col1 FROM t2;
col1
1
3
4
4 row(s) retrieved.
INTERSECT 运算符有一些(但不是所有)与 UNION 运算符相同的限制,但 INTERSECT 不支持使得 UNION 能够返回重复的值的 ALL 关键字。另请参阅主题 对组合的 SELECT 的限制。