UNION和UNION ALL有什么区别?


Answers:


1734

UNION删除重复的记录(结果中的所有列均相同),UNION ALL但不删除。

使用UNION而不是时UNION ALL,性能会受到影响,因为数据库服务器必须做其他工作才能删除重复的行,但是通常您不希望重复(特别是在开发报表时)。

UNION示例:

SELECT 'foo' AS bar UNION SELECT 'foo' AS bar

结果:

+-----+
| bar |
+-----+
| foo |
+-----+
1 row in set (0.00 sec)

UNION ALL示例:

SELECT 'foo' AS bar UNION ALL SELECT 'foo' AS bar

结果:

+-----+
| bar |
+-----+
| foo |
| foo |
+-----+
2 rows in set (0.00 sec)

179
这个含义是,工会是高性能的要少得多,因为它必须扫描结果的重复
马修·沃森

19
UNION ALL确实将具有更高的性能,特别是由于缺少独特的种类。我的一般做法是使用UNION ALL,除非我特别想要重复。
亚当·卡维尼斯

6
只是注意到这里有很多很好的评论/答案,所以我打开了Wiki标志并添加了有关性能的说明...
Jim Harte

250
在现实世界中,诸如Internet之类的网络是瓶颈,在这种情况下,UNION ALL的速度可能比UNION慢。传输许多重复行的成本可能超过查询执行时间的收益。必须根据具体情况对此进行分析。
查尔斯·伯恩斯

23
@AdamCaviness您的评论没有任何意义。
kojow7

285

UNION和UNION ALL都将两个不同SQL的结果连接在一起。它们处理重复项的方式不同。

  • UNION对结果集执行DISTINCT,从而消除了任何重复的行。

  • UNION ALL不会删除重复项,因此比UNION快。

注意:使用此命令时,所有选定的列都必须具有相同的数据类型。

示例:如果我们有两个表,则1)员工和2)客户

  1. 员工表数据:

在此处输入图片说明

  1. 客户表数据:

在此处输入图片说明

  1. UNION示例(删除所有重复的记录):

在此处输入图片说明

  1. UNION ALL示例(仅连接记录,不消除重复项,因此比UNION更快):

在此处输入图片说明


3
“所有选定的列都必须具有相同的数据类型”-实际上,事情并不那么严格(从关系模型的角度来看,这不是一件好事!)。SQL标准规定,除了名称外,它们各自的列描述符必须相同。
一天,2016年

47

UNION删除重复项,UNION ALL但不删除。

为了删除重复项,必须对结果集进行排序,这可能会对UNION的性能产生影响,这取决于要排序的数据量以及各种RDBMS参数的设置(对于PGA_AGGREGATE_TARGET带有WORKAREA_SIZE_POLICY=AUTOor SORT_AREA_SIZESOR_AREA_RETAINED_SIZEif的Oracle WORKAREA_SIZE_POLICY=MANUAL)。

基本上,如果可以在内存中执行排序,则速度会更快,但有关数据量的警告同样适用。

当然,如果需要返回的数据没有重复项,则必须使用UNION,具体取决于数据的来源。

我本来会在第一篇文章中发表评论,以限定“绩效差得多”的评论,但声誉(得分)不足。


1
“为了删除重复项,必须对结果集进行排序”-也许您有一个特定的供应商,但是问题上没有特定于供应商的标签。即使有,您是否可以证明不进行分类就无法删除重复项?
2016年

2
distinct将“隐式”对结果进行排序,因为在有序集上删除重复项会更快。这并不意味着实际上以这种方式对返回的结果集进行排序,但是在大多数情况下,不同的(因此,UNION)将在内部对结果集进行排序。
DevilSuichiro



13

您可以通过运行以下查询来避免重复,并且运行速度仍比UNION DISTINCT(实际上与UNION相同)快得多:

SELECT * FROM mytable WHERE a=X UNION ALL SELECT * FROM mytable WHERE b=Y AND a!=X

注意AND a!=X零件。这比UNION快得多。


4
这将省略行,因此如果a包含NULL值,将无法产生预期的结果。此外,它仍然不会返回与-相同的结果UNION- UNION还会删除子查询返回的重复项,而您的方法则不会。
Frank Schmitt

@FrankSchmitt-感谢您的回答;关于子查询的一点正是我想知道的!
Doradus

11

只是为了在这里的讨论中加上我的两分钱:我们可以将UNION运算符理解为一个纯的,面向SET的UNION-例如,设置A = {2,4,6,8},设置B = {1,2,3,4 },A UNION B = {1,2,3,4,6,8}

当套打交道,你不希望号2和4出现两次,作为一个元素或者不是一组。

但是,在SQL领域中,您可能希望将两个集合中的所有元素一起放在一个“袋子” {2,4,6,8,1,2,3,4}中。为此,T-SQL提供了运算符UNION ALL


2
Nitpick:UNION ALLT-SQL不“提供”。UNION ALL是ANSI SQL标准的一部分,并非特定于MS SQL Server。
Frank Schmitt

1
“ Nitpick”注释可能意味着您不能在TSQL中使用“ Union All”,但是可以。当然,评论并没有这么说,但是阅读它的人可能会推断出它。
JosephDoggie

10

UNION
UNION命令用于从两个表中选择相关信息,非常类似于该JOIN命令。但是,使用该UNION命令时,所有选定的列都必须具有相同的数据类型。使用UNION,仅选择不同的值。

UNION ALL
UNION ALL命令与UNION命令相同,只是UNION ALL选择所有值。

Union和之间的区别Union allUnion all不会消除重复的行,而是仅从所有符合您查询要求的表中提取所有行并将它们组合到一个表中。

一个UNION语句有效地做一个SELECT DISTINCT对结果集。如果您知道所有返回的记录在您的联合中都是唯一的,请UNION ALL改用它,它会提供更快的结果。


8

不确定哪个数据库重要

UNIONUNION ALL应可在所有SQL Server上使用。

您应该避免不必要UNION的操作,因为它们会造成巨大的性能泄漏。根据经验,UNION ALL如果不确定使用哪个。


此问题上没有SQL Server标记。我认为仅由于其通常表现最佳而返回重复项的选项是错误的建议。
一天,2016年

1
@onedaywhen,我猜想OP使用短语“ SQL Servers”作为所有RDBMS(例如MySQL,PostGreSQL,Oracle,SQL Server)的同义词。但是,措词很不幸(当然,我可能会误解)。
Frank Schmitt

@FrankSchmitt:您列出的所有产品都不是真正的RDBMS :)
一天

1
@oneday何时需要详细说明?至少en.wikipedia.org/wiki/Relational_database_management_system似乎同意我的意见-它明确提到了Microsoft SQL Server,Oracle数据库和MySQL。或者,您是否对Oracle和Oracle数据库之间的区别不屑一顾?
Frank Schmitt

8

UNION-产生不同的记录,



UNION ALL-产生所有记录,包括重复记录。

两者都是阻塞运算符,因此我个人更喜欢随时使用JOINS而不是阻塞运算符(UNION,INTERSECT,UNION ALL等)。

为了说明为什么Union操作与Union All相比效果较差,请参见以下示例。

CREATE TABLE #T1 (data VARCHAR(10))

INSERT INTO #T1
SELECT 'abc'
UNION ALL
SELECT 'bcd'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'def'
UNION ALL
SELECT 'efg'


CREATE TABLE #T2 (data VARCHAR(10))

INSERT INTO #T2
SELECT 'abc'
UNION ALL
SELECT 'cde'
UNION ALL
SELECT 'efg'

在此处输入图片说明

以下是UNION ALL和UNION操作的结果。

在此处输入图片说明

UNION语句有效地对结果集执行SELECT DISTINCT。如果您知道所有返回的记录在您的联合中都是唯一的,请改用UNION ALL,这样可以更快地得到结果。

使用UNION会在执行计划中导致不同的排序操作。证明此陈述的证据如下所示:

在此处输入图片说明


3
这个答案中的所有内容都已经说过,太混乱而无用了(建议在工会做不同的事情时对工会进行联接,以“阻塞”为理由而不解释您的意思或适用于哪些数据库服务器),或者极具误导性(您的屏幕截图中的百分比不适用于UNION/的实际实际使用UNION ALL)。

阻塞运算符是TSQL中众所周知的运算符。阻塞运算符所做的一切都可以通过Joins来实现,反之亦然。图片中圈出了“不同的排序”操作,以显示为什么union的所有性能都优于union,并确切显示其在执行计划中的位置。随时将更多数据添加到表T1和T2中,以计算百分比!
DBA

从技术上讲,您union可以结合使用joins和一些确实令人讨厌的cases 来 产生a的结果,但是它使查询darn-near无法读取和维护,并且以我的经验,这对于性能也很糟糕。比较:select foo.bar from foo union select fizz.buzz from fizz反对select case when foo.bar is null then fizz.buzz else foo.bar end from foo join fizz where foo.bar is null or fizz.buzz is null
Devin Lamothe

@DBA您的答案仅与MS SQL Server用户有关。OP从未提及他们正在使用的RDBMS-他们可能正在使用MySQL,PostgreSQL,Oracle,SQLite等...
Frank Schmitt

6

联合用于从两个表中选择不同的值,其中联合所有用于从表中选择所有值,包括重复项


6

理解维恩图非常好。

这是到源的链接。有一个很好的描述。

在此处输入图片说明


5
您的第二张图片表明两者在互不排斥时是互斥的。图片应该显示与第一张相同,但()第二次显示“相交椭圆” 。实际上,再三考虑,因为union all结果不是集合,所以您不应该尝试使用维恩图来绘制结果!
一天,2016年

5

(来自Microsoft SQL Server联机丛书)

联盟[全部]

指定将多个结果集合并并作为单个结果集返回。

所有

将所有行合并到结果中。这包括重复项。如果未指定,则删除重复的行。

UNION如果将重复行发现为like,则会花费很长时间DISTINCT

SELECT * FROM Table1
UNION
SELECT * FROM Table2

等价于:

SELECT DISTINCT * FROM (
    SELECT * FROM Table1
    UNION ALL
    SELECT * FROM Table2) DT

DISTINCT结果套用到结果的副作用是对结果进行排序操作

UNION ALL结果将显示为结果的任意顺序,但UNION结果将显示为ORDER BY 1, 2, 3, ..., n (n = column number of Tables)应用于结果。没有任何重复的行时,您会看到这种副作用。


5

我加一个例子

联盟合并的速度较慢->较慢,因为它需要比较(在Oracle SQL开发人员中,选择查询,按F10键以查看成本分析)。

UNION ALL,它合并时没有不同->更快。

SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;

SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual
UNION ALL
SELECT to_date(sysdate, 'yyyy-mm-dd') FROM dual;

2

UNION 将两个结构兼容表的内容合并到一个组合表中。

  • 区别:

UNION和之间的区别UNION ALLUNION will省略重复记录,而UNION ALL将包括重复记录。

Union结果集按升序排序,而UNION ALL结果集不排序

UNIONDISTINCT对结果集执行,这样它将消除所有重复的行。而UNION ALL不会删除重复项,因此它比UNION。* 更快。

注意 的性能UNION ALL通常会比更好UNION,因为UNION要求服务器执行删除所有重复项的附加工作。因此,在确定没有重复项或没有重复项的问题的情况下,UNION ALL出于性能原因,建议使用。


1
“联合结果集按升序排序”-除非存在ORDER BY,否则不能保证排序结果。也许您在考虑一个特定的SQL供应商(即使那样,升序到底是什么...?),但是此问题没有供应商=特定的标记。
一天,2016年

“合并两个结构兼容的表的内容” –我认为您已经很好地说明了这一部分:)
一天,2016年

2

假设您有两个表TeacherStudent

两者都有这样的具有不同名称的4列

Teacher - ID(int), Name(varchar(50)), Address(varchar(50)), PositionID(varchar(50))

在此处输入图片说明

Student- ID(int), Name(varchar(50)), Email(varchar(50)), PositionID(int)

在此处输入图片说明

您可以对具有相同列数的两个表应用UNION或UNION ALL。但是它们具有不同的名称或数据类型。

当您UNION在2个表上应用操作时,它会忽略所有重复的条目(一个表中row的所有column值与另一个表相同)。像这样

SELECT * FROM Student
UNION
SELECT * FROM Teacher

结果将是

在此处输入图片说明

当您UNION ALL在2个表上应用操作时,它将返回所有重复项(如果2个表中某行的任何列值之间存在差异)。像这样

SELECT * FROM Student
UNION ALL
SELECT * FROM Teacher

输出量 在此处输入图片说明

性能:

显然,UNION ALL性能比UNION更好,因为它们执行附加任务以删除重复值。您可以在MSSQL中ctrl + L从“ 执行估计时间”中进行检查


真?要获得四行结果?我认为这是您要UNION传达意图(即不重复)的一种情况,因为UNION ALL不可能绝对地获得任何现实生活中的性能提升。
一天,2016年

2

用简单的话来说,UNION和UNION ALL之间的区别是UNION将省略重复的记录,而UNION ALL将包括重复的记录。


1

我想补充一件事-

联合:-结果集按升序排序。

全部合并:-结果集未排序。两个查询输出仅被追加。


没错!UNION可能会更改两个子结果的顺序。
gracchus 2015年

6
错了 一UNION排序结果按升序排列。您在结果中看到的任何未使用的排序order by都是纯巧合。DBMS可以自由使用它认为有效的删除重复项的任何策略。这可能是排序,但也可能是哈希算法或完全不同的东西-策略将随行数而变化。一个union出现排序与100行可能不100.000行
a_horse_with_no_name

2
如果查询中没有ORDER BY子句,则RDBMS可以自由返回任何顺序的行。从UNION操作返回的结果集以“升序”返回的观察结果只是数据库执行的“ sort unique”操作的副产品无法保证观察到的行为。所以不要依赖它。如果规范是按特定顺序返回行,则添加一个适当的ORDER BY子句。
spencer7593

1

SQL中Union vs Union ALL之间的区别

什么是SQL中的联合?

UNION运算符用于合并两个或多个数据集的结果集。

Each SELECT statement within UNION must have the same number of columns
The columns must also have similar data types
The columns in each SELECT statement must also be in the same order

联盟与联盟全部示例


1

重要!Oracle和Mysql之间的区别:假设t1 t2之间没有重复的行,但是它们各自都有重复的行。示例:t1的销售额自2017年开始,t2的销售额自2018年开始

SELECT T1.YEAR, T1.PRODUCT FROM T1

UNION ALL

SELECT T2.YEAR, T2.PRODUCT FROM T2

在ORACLE UNION中,ALL从两个表中提取所有行。在MySQL中也会发生相同的情况。

然而:

SELECT T1.YEAR, T1.PRODUCT FROM T1

UNION

SELECT T2.YEAR, T2.PRODUCT FROM T2

ORACLE中,UNION从两个表中获取所有行,因为t1和t2之间没有重复的值。另一方面,在MySQL中,结果集将具有较少的行,因为在表t1以及表t2中将存在重复的行!


0

另一方面,UNION会删除重复的记录,而UNION ALL不会。但是,需要检查将要处理的大量数据,并且列和数据类型必须相同。

由于union在内部使用“独特”行为来选择行,因此,在时间和性能方面会更加昂贵。喜欢

select project_id from t_project
union
select project_id from t_project_contact  

这给了我2020年的记录

在另一方面

select project_id from t_project
union all
select project_id from t_project_contact

给我超过17402行

在优先级角度上,两者具有相同的优先级。


0

如果没有ORDER BY,则a UNION ALL可能会带回行,而a UNION会使您等到查询的最后,才立即给您整个结果集。这可以在超时情况下有所作为-UNION ALL使连接保持原样。

因此,如果您遇到超时问题,并且没有排序,并且重复不是问题,那么UNION ALL可能会很有帮助。


但是您的第一部分结果可能会重复多次行:这有多有用?
一天,2016年

0

UNION和UNION ALL用于合并两个或多个查询结果。

UNION命令从两个表中选择不同的相关信息,这将消除重复的行。

另一方面,UNION ALL命令从两个表中选择所有值,从而显示所有行。


0

作为一种习惯,请始终使用UNION ALL。在特殊情况下,当您需要消除可能非常混乱的重复项时,请仅使用UNION,并且可以在此处的其他注释中阅读全部内容。


0

UNION ALL也适用于更多数据类型。例如,当尝试合并空间数据类型时。例如:

select a.SHAPE from tableA a
union
select b.SHAPE from tableB b

会抛出

The data type geometry cannot be used as an operand to the UNION, INTERSECT or EXCEPT operators because it is not comparable.

但是union all不会。


-2

唯一的区别是:

“ UNION”删除重复的行。

“ UNION ALL”不会删除重复的行。


13
与接受的答案相比,这如何增加任何价值?
尼克,

@Nick是简短的答案。
Mostafa Vatanpour

如果必须阅读已接受答案的重要部分以获取此数据,则简短一点可能是一个优势。但是在这种情况下,被接受的答案在第一句中包含了所有这些信息,然后继续详细讨论了差异的含义。
dmckee ---前主持人小猫,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.