ChatGPT解决这个技术问题 Extra ChatGPT

UNION 和 UNION ALL 有什么区别?

UNIONUNION ALL 有什么区别?


9
9 revs, 7 users 64%

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

使用 UNION 而不是 UNION ALL 会降低性能,因为数据库服务器必须执行额外的工作来删除重复的行,但通常您不希望重复(尤其是在开发报表时)。

要识别重复项,记录必须是可比较的类型以及兼容的类型。这将取决于 SQL 系统。例如,系统可能会截断所有长文本字段以制作短文本字段以进行比较(MS Jet),或者可能拒绝比较二进制字段(ORACLE)

联合示例:

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)

这意味着联合的性能要差得多,因为它必须扫描结果以查找重复项
刚刚注意到这里有很多好的评论/答案,所以我打开了wiki标志并添加了关于性能的注释......
在互联网等网络成为瓶颈的实际情况下,UNION ALL 可能比 UNION 慢。传输许多重复行的成本可能超过查询执行时间的好处。这必须根据具体情况进行分析。
s
shA.t

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

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

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

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

示例:如果我们有两个表,1) Employee 和 2) Customer

员工表数据:

https://i.stack.imgur.com/huYEL.png

客户表数据:

https://i.stack.imgur.com/FEaKe.png

UNION 示例(它删除所有重复记录):

https://i.stack.imgur.com/lLiS1.png

UNION ALL 示例(它只是连接记录,而不是消除重复,因此它比 UNION 更快):

https://i.stack.imgur.com/n5gvq.png


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

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

为了去除重复,必须对结果集进行排序,这可能会影响 UNION 的性能,具体取决于被排序的数据量,以及各种 RDBMS 参数的设置(对于Oracle PGA_AGGREGATE_TARGETWORKAREA_SIZE_POLICY=AUTOSORT_AREA_SIZESOR_AREA_RETAINED_SIZE 如果 WORKAREA_SIZE_POLICY=MANUAL )。

基本上,如果可以在内存中进行排序,则排序会更快,但同样需要注意数据量。

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

我会在第一篇文章中发表评论以限定“性能低得多”的评论,但没有足够的声誉(积分)来这样做。


“为了删除重复项,必须对结果集进行排序”——也许你有一个特定的供应商,但问题上没有特定于供应商的标签。即使有,你能证明不排序就不能删除重复项吗?
distinct 将“隐式”对结果进行排序,因为在已排序的集合上删除重复项更快。这并不意味着返回的结果集实际上是这样排序的,但在大多数情况下,不同的(因此,UNION)将在内部对结果集进行排序。
M
Michiel Overeem

在 ORACLE 中:UNION 不支持 BLOB(或 CLOB)列类型,UNION ALL 支持。


这同样适用于具有不可比较列类型的 MS SQL,如 XML
G
George Mauer

UNION 和 UNION ALL 之间的基本区别是联合操作从结果集中消除了重复的行,但 union all 在加入后返回所有行。

来自http://zengin.wordpress.com/2007/07/31/union-vs-union-all/


不幸的是,链接的 wordpress.com 文章似乎不再可用。哎呀!找不到那个页面 乔治,你有一个备用网址吗?
s
shA.t

UNION
UNION 命令用于从两个表中选择相关信息,很像 JOIN 命令。但是,当使用 UNION 命令时,所有选定的列都需要具有相同的数据类型。使用 UNION,仅选择不同的值。

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

UnionUnion all 之间的区别在于,Union all 不会消除重复的行,它只是从适合您查询细节的所有表中提取所有行并将它们组合到一个表中。

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


I
Ihor Vorotnov

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

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

注意 AND a!=X 部分。这比 UNION 快得多。


如果 a 包含 NULL 值,这将省略行,因此无法产生预期的结果。此外,它仍然不会返回与 UNION 相同的结果 - UNION 还会删除子查询返回的重复项,而您的方法不会。
@FrankSchmitt - 感谢您的回答;关于子查询的这一点正是我想知道的!
P
Peter Perháč

只是为了在这里的讨论中添加我的两分钱:可以将 UNION 运算符理解为纯的、面向 SET 的 UNION - 例如 set A={2,4,6,8}, set 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


Nitpick:T-SQL 没有“提供”UNION ALLUNION ALL 是 ANSI SQL 标准的一部分,并不特定于 MS SQL Server。
“Nitpick”评论可能暗示您不能在 TSQL 中使用“Union All”,但可以。当然,评论并没有这么说,但是阅读它的人可能会推断出来。
D
DBA

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'

https://i.stack.imgur.com/kdD4p.jpg

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

https://i.stack.imgur.com/LpjWD.jpg

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

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

https://i.stack.imgur.com/QmQlL.jpg


这个答案中的所有内容都已经说过了,太令人困惑而无用(建议在联合执行不同的操作时加入联合,将“阻塞”作为原因而不解释您的意思或它适用于哪些数据库服务器),或者具有高度误导性(您在屏幕截图中的百分比不适用于 UNION/UNION ALL 的实际使用)。
阻塞运算符是 TSQL 中众所周知的运算符。阻塞操作符所做的一切都可以通过 Joins 来实现,反之则不行。图中圈出的 Distinct Sort 操作说明了为什么 union all 比 union 执行得更好,同时也准确地显示了它在执行计划中的位置。随意将更多数据添加到表 T1 和 T2 以玩弄百分比!
从技术上讲,您可以使用 join 和一些非常讨厌的 case 的组合来生成 union 的结果,但是它使查询几乎无法阅读和维护,并且根据我的经验,它是 性能很差。比较:select foo.bar from foo union select fizz.buzz from fizzselect 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
@DBA 您的答案仅与 MS SQL Server 用户相关。 OP 从未提及他们正在使用的 RDBMS - 他们可能正在使用 MySQL、PostgreSQL、Oracle、SQLite...
s
shA.t

不确定哪个数据库很重要

UNIONUNION ALL 应该适用于所有 SQL Server。

您应该避免不必要的UNION,它们是巨大的性能泄漏。根据经验,如果您不确定要使用哪个,请使用 UNION ALL


这个问题没有 SQL Server 标记。我认为仅仅因为它通常表现最好而返回重复项的选项是错误的建议。
@onedaywhen 我猜 OP 使用短语“SQL Servers”作为所有 RDBMS(例如 MySQL、PostGreSQL、Oracle、SQL Server)的同义词。不过,措辞很不幸(当然,我可能弄错了)。
@FrankSchmitt:您列出的所有产品都不是真正的 RDBMS :)
@onedaywhen 需要详细说明吗?至少 en.wikipedia.org/wiki/Relational_database_management_system 似乎同意我的看法 - 它明确提到了 Microsoft SQL Server、Oracle 数据库和 MySQL。或者您是否对 Oracle 和 Oracle 数据库之间的区别很挑剔?
@FrankSchmitt,对我来说,这就像 Windows,而不是房屋墙壁上的洞,而不是 M$ 操作系统。 “基于意见”当然:)
p
pedram

用维恩图很好理解。

这是源的link。有一个很好的描述。

https://i.stack.imgur.com/M0gvT.png


你的第二张照片表明两者是相互排斥的,但它们不是。图片应该与第一个显示相同,但第二次显示“交叉椭圆”()。实际上,再想一想,因为 union all 结果不是集合,所以您不应该尝试使用维恩图来绘制它!
维恩图是图片集,但 SQL 表是包而不是集。所以你还没有解释如何阅读它们。事实证明这很复杂。如此复杂,它们无助于解释。第二张图也不是维恩图。你也没有给予正确的信用。 Help center Meta Stack Overflow Meta Stack Exchange 附注 Why are images of text, code and mathematical expressions discouraged?
佚名

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


s
shA.t

(来自 Microsoft SQL Server 联机丛书)

联合[全部]

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

全部

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

UNION 将花费太长时间,因为在结果中应用了类似 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) 应用于结果。当您没有任何重复行时,您可以看到此副作用。


J
James Graham

我添加一个例子,

UNION,它与distinct合并-->较慢,因为它需要比较(在Oracle SQL developer中,选择查询,按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;

p
pedram

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

区别:

UNIONUNION ALL 之间的区别在于 UNION will 省略重复记录,而 UNION ALL 将包含重复记录。

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

UNION 对其结果集执行 DISTINCT,以便消除任何重复的行。而 UNION ALL 不会删除重复项,因此它比 UNION 快。*

注意 UNION ALL 的性能通常会优于 UNION,因为 UNION 需要服务器执行额外的工作以删除任何重复项.因此,如果确定不会有任何重复,或者重复不成问题,出于性能原因,建议使用 UNION ALL


“联合结果集按升序排序”——除非有 ORDER BY,否则不能保证排序结果。也许您心中有一个特定的 SQL 供应商(即使如此,升序到底是什么......?)但是这个问题没有 vendor=specific 标记。
“合并两个结构兼容表的内容”——我认为你已经很好地说明了这部分:)
r
reza.cse08

假设你有两张表 Teacher & Student

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

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

https://i.stack.imgur.com/8uYB7.png

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

https://i.stack.imgur.com/lyCoB.png

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

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

SELECT * FROM Student
UNION
SELECT * FROM Teacher

结果将是

https://i.stack.imgur.com/FNzdi.png

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

SELECT * FROM Student
UNION ALL
SELECT * FROM Teacher

https://i.stack.imgur.com/DTBLt.png

表现:

显然 UNION ALL 的性能比 UNION 更好,因为它们会执行额外的任务来删除重复值。您可以在 MSSQL 上按 ctrl+L 从 Execution Estimated Time 中检查


真的吗?为了四排的结果?!我认为在这种情况下,您可能希望使用 UNION 来传达意图(即没有重复),因为 UNION ALL 不可能在绝对意义上给出任何现实生活中的性能提升。
D
DhruvJoshi

我还想补充一件事——

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

联合所有:- 结果集未排序。两个查询输出只是被附加。


真的 ! UNION 可能会更改两个子结果的顺序。
这是错误的。 UNIONNOT按升序对结果进行排序。您在未使用 order by 的结果中看到的任何排序纯属巧合。 DBMS 可以自由使用任何它认为有效的策略来删除重复项。这可能是排序,但它也可能是散列算法或完全不同的东西 - 策略将随着行数而改变。以 100 行排序出现union 可能不是 100.000 行
如果查询中没有 ORDER BY 子句,RDBMS 可以自由地返回 any 序列中的行。观察到来自 UNION 操作的结果集“按升序”返回只是数据库执行的“排序唯一”操作的副产品保证观察到的行为。所以不要依赖它。如果规范是以特定顺序返回行,则添加适当的 ORDER BY 子句。
P
Pawan Kumar

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

由于联合在内部使用“不同”行为来选择行,因此在时间和性能方面成本更高。喜欢

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 行

从优先级的角度来看,两者具有相同的优先级。


A
AjV Jsy

如果没有 ORDER BY,则 UNION ALL 可能会带回行,而 UNION 会让您等到查询的最后,然后再一次为您提供整个结果集。这可以在超时情况下产生影响 - UNION ALL 使连接保持活动状态。

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


但是您的第一组结果可能是一行重复多次:这有多大用处?!
U
Usman Maqbool

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

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

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


S
Suraj Rao

重要的! 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 中都会有重复的行!


这是错误的。 x union yselect distinct * from (x union all y)select 1 from dual union select 1 from dual & (select 1 from dual union all select 1 from dual) union select 1 from dual 都返回 1 行。 PS我不知道是否通过t1 & t2 你的意思是 T1 & T1,但重要的是选择中的内容。 PS对于UNION(不同的)示例,就重复项而言,您没有清楚地说什么是输入&对于每个 DBMS,它返回什么或为什么。使用足够的单词 &句子&引用部分示例要清楚。
D
Dowlers

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 不会。