"Union all"的用途是什么?

7

我并不是在问它们之间的区别,我的问题是什么时候需要使用 "Union All"?


谢谢,你们所有的回答都说只有两个主要问题:1)重复行和2)性能。这意味着我们可以使用其中任何一个,所以我不明白为什么我们不能在这个查询中使用union。使用tempData作为临时表 ( 选择32作为col1,char(32)作为col2 union all 选择col1+1,char(col1+1) from tempData where col1 < 127 ) 从tempData中选择* - Jeevan Bhatt
@Jeevan Bhatt - 当你在查询中使用'UNION'而不是'UNION ALL'时会发生什么?你使用的是哪个数据库? - Bob Jarvis - Слава Україні
@Jeevan Bhatt - 经过一番查看你的查询,我认为存在一些语法错误,这些错误导致它无法执行。CTE中的第一个子查询缺少FROM子句,而第二个子查询在CTE内引用了CTE,这是不允许的。你的查询想要实现什么目标? - Bob Jarvis - Слава Україні
@Bob- 我正在使用 SQL Server 2008,在使用 'union' 而非 'union all' 时会出现错误:递归公共表达式“tempData”不包含顶层 UNION ALL 运算符。 - Jeevan Bhatt
@Jeevan Bhatt - 显然,SQL Server 2008允许递归CTE,但我只有Oracle可供测试,而且似乎Oracle不允许递归CTE。因此,在这里我无法提供太多帮助。但是,错误消息似乎表明在SQL Server 2008中,递归CTE中的第一个UNION运算符必须是UNION ALL。祝你好运。 - Bob Jarvis - Слава Україні
@Jeevan,CTE中可用的从句有一些限制-请参见此问题和答案:http://stackoverflow.com/questions/3903344/why-are-ctes-unable-to-use-grouping-and-other-clauses。UNION在SELECT中包含隐式DISTINCT,而UNION ALL则不包括。 - user359040
12个回答

17

当需要多个数据集的行时,应使用 UNION ALL ,否则使用 UNION 时会删除这些行的多个'副本'。此外,由于数据库引擎不需要确定结果集之间的重复项,因此在查询结束时,使用 UNION ALL 也可能更快。


3
提到性能方面要点赞,这几乎是至关重要的,需要了解UNION和UNION ALL对于较大的表格的影响,对于大型结果集来说,UNION会比UNION ALL慢数个数量级(因为大多数情况下去除重复项意味着构建临时索引;对于较小的结果集,这不会那么昂贵,结果集的大小是返回的行数)。 - Unreason
1
我会说“可以容忍”多个副本,而不是“需要”。例如,当您说WHERE ForeignKey IN (SELECT Id FROM view1 UNION ALL SELECT Id FROM view2)时。您不需要两者,但可以容忍两者。 - Mark Sowul
“当你确实需要多个行的'副本'时…”:在什么情况下会出现这种情况?你能举个例子吗? - kotchwane

7
  • UNION将删除重复项
  • UNION ALL不会删除重复项

示例

SELECT 1 AS foo
UNION
SELECT 1 AS foo

= one row

SELECT 1 AS foo
UNION ALL
SELECT 1 AS foo

= two rows

1
如果您正在执行大量的JOIN操作并且存在冗余行,您会使用GROUP BY而不是UNION吗?UNION和DISTINCT之间有什么区别? - meder omuraliev
@meder:使用GROUP BY去除重复是不正确的,它是用于聚合的。DISTINCT适用于每个SELECT语句。也就是说,如果需要,我可以使用SELECT DISTINCT.. UNION ALL SELECT ...。这意味着要去掉第一个子句中的重复行,但在UNION中保留所有行。 - gbn
因为楼主说“我不是在问它们之间的区别”,所以被投票否决。 - jcansell

4
一个例子可以让它更清晰明了:
mysql> select * from tmp1;
+------+
| a    |
+------+
| foo1 |
| foo2 |
+------+
2 rows in set (0.00 sec)

mysql> select * from tmp2;
+------+
| a    |
+------+
| foo2 |
| foo3 |
| foo4 |
+------+
3 rows in set (0.00 sec)

mysql> select * from tmp1 union select * from tmp2;
+------+
| a    |
+------+
| foo1 |
| foo2 |   # DUPLICATES REMOVED.
| foo3 |
| foo4 |
+------+
4 rows in set (0.00 sec)

mysql> select * from tmp1 union all select * from tmp2;
+------+
| a    |
+------+
| foo1 |
| foo2 |
| foo2 |    # DUPLICATES NOT REMOVED.
| foo3 |
| foo4 |
+------+
5 rows in set (0.00 sec)

关于何时使用UNION ALL的问题:

如果您不关心结果集是否有重复行,或者您知道不会有任何重复行,则请使用UNION ALL而不是UNION


3
由于结果将是一个表格,每个表格都应该有一个键,并且UNION可以确保唯一的行,理论上应该始终使用UNION。然而,由于UNION ALL不能确保唯一的行,如果您可以确定两个表已经包含唯一的行,则在实践中可能更喜欢UNION ALL,因为它可以提高性能。
顺便说一下,选择SELECT DISTINCTSELECT ALL之间的选择也适用于相同的逻辑。

2

需要使用它们取决于您的要求。UNION和UNION ALL之间的区别在于,UNION ALL不会删除重复行。


我并不是在询问它们之间的区别。 - jcansell
哇,我没想到在将近10年后还会收到评论 :)。你现在还有关于 UNION 的问题需要我的帮助吗? - Tomas Jansson

1

Union all 用于将多个数据集合并为一个数据集,但它不会删除重复项。


0

当我们不需要从记录集中排除重复行时


0

当两个结果集具有相同的列(数量和类型)时,您可以使用UNION ALL将它们连接(追加)成一个单独的结果集。


0
除了重复性差异和性能之外,应该考虑的情况是当您希望将结果完全不同但在操作上可以给出共同结果的情况下进行联合的场景,仅举一个例子。
    Select name from table
     Union all
    Select max(name) from table

      Vs

     Select name from table
     Union 
    Select max(name) from table

在某种情况下,如果您的max(name)与name相同,则union将给出一条记录,而union all将给出两条记录。但是,为了知道name的最大值与列表中特定名称的最大值相同,那么请使用union all。我的意思是这是非常基本的场景。在联接语句的情况下,union all可能会产生很大的差异,通常可能被设置为不同,但在操作时可能会导致相同的结果。

-1

默认情况下,UNION将消除重复的值。如果您将UNION替换为UNION ALL,则不再消除重复值。 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接