SQL:UNION与SELECT DISTINCT和UNION ALL子查询相同吗

SQL:UNION与SELECT DISTINCT和UNION ALL子查询相同吗,sql,database,Sql,Database,这两条SQL语句在所有场景中都相同吗 SELECT DISTINCT * FROM (SELECT * FROM tablename UNION ALL SELECT * FROM tablename2) dummyname 及 我总是发现UNION的一个独特之处是,它删除了所有不明确的行,即使这些不明确的行出现在UNION子句的单个部分中。例如,假设tablename有一列:amt INT。假设amt INT不是主键,并且没有任何唯一约束。假设我有两行,其中amt=20。不管我使用哪种并集

这两条SQL语句在所有场景中都相同吗

SELECT DISTINCT * FROM 
(SELECT * FROM tablename UNION ALL SELECT * FROM tablename2) dummyname

我总是发现UNION的一个独特之处是,它删除了所有不明确的行,即使这些不明确的行出现在UNION子句的单个部分中。例如,假设tablename有一列:amt INT。假设amt INT不是主键,并且没有任何唯一约束。假设我有两行,其中amt=20。不管我使用哪种并集,结果集中只会出现这两行中的一行


我向其他人解释了这种行为,然后想出了上面的例子来演示工会的行为。。。我相信上述两种说法是相同的(总是),但我只是想确保我所说的是正确的。是否存在上述两条SQL语句无法生成完全相同的结果集的边缘情况?

这两个版本是相同的:
UNION
在功能上等同于
UNION ALL
上的
SELECT DISTINCT

UNION
删除表内的重复值以及两个表之间共享的值

我应该注意到,从性能的角度来看,以下操作通常比仅使用
联合
更快:

select distinct t.col1, t.col2
from t
union
select distinct t1.col1, t.col2
from t1;

这可能违反直觉。但是,如果表中的
(col1,col2)
上有索引,那么它可以用于
选择distinct
,减少
联合的行数。一些优化器可能会错过简化输入的机会。

这两个版本是相同的:
UNION
在功能上等同于
UNION ALL
上的
SELECT DISTINCT

UNION
删除表内的重复值以及两个表之间共享的值

我应该注意到,从性能的角度来看,以下操作通常比仅使用
联合
更快:

select distinct t.col1, t.col2
from t
union
select distinct t1.col1, t.col2
from t1;

这可能违反直觉。但是,如果表中的
(col1,col2)
上有索引,那么它可以用于
选择distinct
,减少
联合的行数。一些优化器可能错过了简化输入的机会。

总之,是的,您可以找到以下解释:

结果1:

结果2:


简而言之,是的,您可以找到以下解释:

结果1:

结果2:


这里有一篇很好的文章可以清楚地解释这一点:是的,它们是相同的,只是请记住不要在union子句中使用
*
。因为你可以得到一个专栏,地狱。@JorgeCampos我甚至可以说永远不用。我完全同意你的观点!谢谢你提到它@GarethD@JorgeCampos和GarethD公平点,值得一提。我在这里写的只是粗略的SQL来说明这一点。这里有一篇很好的文章可以清楚地解释这一点:是的,它们是相同的,只是记住永远不要在union子句中使用
*
。因为你可以得到一个专栏,地狱。@JorgeCampos我甚至可以说永远不用。我完全同意你的观点!谢谢你提到它@GarethD@JorgeCampos和GarethD公平点,值得一提。我在这里写的只是粗略的SQL来说明这一点。
/* Declare First Table */
DECLARE @Table1 TABLE (ColDetail VARCHAR(10))
INSERT INTO @Table1
SELECT 'First'
UNION ALL
SELECT 'Second'
UNION ALL
SELECT 'Third'
UNION ALL
SELECT 'Fourth'
UNION ALL
SELECT 'Fifth'
/* Declare Second Table */
DECLARE @Table2 TABLE (ColDetail VARCHAR(10))
INSERT INTO @Table2
SELECT 'First'
UNION ALL
SELECT 'Third'
UNION ALL
SELECT 'Fifth'

SELECT DISTINCT * FROM (SELECT * FROM @Table1 UNION ALL SELECT * FROM @Table2) dummyname
SELECT * FROM @Table1 UNION SELECT * FROM @Table2