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)
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
UNION
删除重复项,而 UNION ALL
不删除。
为了去除重复,必须对结果集进行排序,这可能会影响 UNION 的性能,具体取决于被排序的数据量,以及各种 RDBMS 参数的设置(对于Oracle PGA_AGGREGATE_TARGET
与 WORKAREA_SIZE_POLICY=AUTO
或 SORT_AREA_SIZE
和 SOR_AREA_RETAINED_SIZE
如果 WORKAREA_SIZE_POLICY=MANUAL
)。
基本上,如果可以在内存中进行排序,则排序会更快,但同样需要注意数据量。
当然,如果您需要返回没有重复的数据,那么您必须使用 UNION,具体取决于数据的来源。
我会在第一篇文章中发表评论以限定“性能低得多”的评论,但没有足够的声誉(积分)来这样做。
在 ORACLE 中:UNION 不支持 BLOB(或 CLOB)列类型,UNION ALL 支持。
UNION 和 UNION ALL 之间的基本区别是联合操作从结果集中消除了重复的行,但 union all 在加入后返回所有行。
来自http://zengin.wordpress.com/2007/07/31/union-vs-union-all/
UNION
UNION
命令用于从两个表中选择相关信息,很像 JOIN
命令。但是,当使用 UNION
命令时,所有选定的列都需要具有相同的数据类型。使用 UNION
,仅选择不同的值。
UNION ALL
UNION ALL
命令与 UNION
命令相同,只是 UNION ALL
选择所有值。
Union
和 Union all
之间的区别在于,Union all
不会消除重复的行,它只是从适合您查询细节的所有表中提取所有行并将它们组合到一个表中。
UNION
语句有效地对结果集执行 SELECT DISTINCT
。如果您知道返回的所有记录在您的联合中都是唯一的,请改用 UNION ALL
,它会提供更快的结果。
通过运行如下查询,您可以避免重复并且仍然比 UNION DISTINCT(实际上与 UNION 相同)运行得更快:
SELECT * FROM mytable WHERE a=X UNION ALL SELECT * FROM mytable WHERE b=Y AND a!=X
注意 AND a!=X
部分。这比 UNION 快得多。
UNION
相同的结果 - UNION
还会删除子查询返回的重复项,而您的方法不会。
只是为了在这里的讨论中添加我的两分钱:可以将 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
。
UNION ALL
。 UNION ALL
是 ANSI SQL 标准的一部分,并不特定于 MS SQL Server。
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
的实际使用)。
join
和一些非常讨厌的 case
的组合来生成 union
的结果,但是它使查询几乎无法阅读和维护,并且根据我的经验,它是 也性能很差。比较: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
不确定哪个数据库很重要
UNION
和 UNION ALL
应该适用于所有 SQL Server。
您应该避免不必要的UNION
,它们是巨大的性能泄漏。根据经验,如果您不确定要使用哪个,请使用 UNION ALL
。
用维恩图很好理解。
这是源的link。有一个很好的描述。
https://i.stack.imgur.com/M0gvT.png
()
。实际上,再想一想,因为 union all
结果不是集合,所以您不应该尝试使用维恩图来绘制它!
union 用于从两个表中选择不同的值,其中 union all 用于选择所有值,包括表中的重复值
(来自 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)
应用于结果。当您没有任何重复行时,您可以看到此副作用。
我添加一个例子,
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;
UNION
将两个结构兼容的表格的内容合并到一个组合表格中。
区别:
UNION
和 UNION ALL
之间的区别在于 UNION will
省略重复记录,而 UNION ALL
将包含重复记录。
Union
结果集按升序排序,而 UNION ALL
结果集未排序
UNION
对其结果集执行 DISTINCT
,以便消除任何重复的行。而 UNION ALL
不会删除重复项,因此它比 UNION
快。*
注意: UNION ALL
的性能通常会优于 UNION
,因为 UNION
需要服务器执行额外的工作以删除任何重复项.因此,如果确定不会有任何重复,或者重复不成问题,出于性能原因,建议使用 UNION ALL
。
ORDER BY
,否则不能保证排序结果。也许您心中有一个特定的 SQL 供应商(即使如此,升序到底是什么......?)但是这个问题没有 vendor=specific 标记。
假设你有两张表 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
不可能在绝对意义上给出任何现实生活中的性能提升。
我还想补充一件事——
联合:- 结果集按升序排序。
联合所有:- 结果集未排序。两个查询输出只是被附加。
UNION
将NOT按升序对结果进行排序。您在未使用 order by
的结果中看到的任何排序纯属巧合。 DBMS 可以自由使用任何它认为有效的策略来删除重复项。这可能是排序,但它也可能是散列算法或完全不同的东西 - 策略将随着行数而改变。以 100 行排序出现的 union
可能不是 100.000 行
ORDER BY
子句。
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 行
从优先级的角度来看,两者具有相同的优先级。
如果没有 ORDER BY
,则 UNION ALL
可能会带回行,而 UNION
会让您等到查询的最后,然后再一次为您提供整个结果集。这可以在超时情况下产生影响 - UNION ALL
使连接保持活动状态。
因此,如果您遇到超时问题,并且没有排序,并且重复不是问题,那么 UNION ALL
可能会很有帮助。
UNION 和 UNION ALL 用于组合两个或多个查询结果。
UNION 命令从两个表中选择不同的和相关的信息,这将消除重复的行。
另一方面,UNION ALL 命令从两个表中选择所有值,显示所有行。
重要的! 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 y
是 select 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,它返回什么或为什么。使用足够的单词 &句子&引用部分示例要清楚。
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
不会。