在执行以下两个查询时(重点关注两个星号 * ____ * 之间的部分),我真的很想知道 UNION ALL 的位置如何改变输出。我无法理解。
查询1
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
*UNION All SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL*
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
查询结果
NAME MARKS
Jack 100
查询2
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
*UNION ALL SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL*
查询结果
NAME MARKS
Jack 100
Jack 100
如果不指定括号,则
select
将依次执行。所有集合运算符 minus
、union
、union all
、intersect
具有相同的优先级。
Oracle Documentation
在第一个查询中,
UNION
在最后执行,因此每个查询不会有重复行。在第二个中,UNION ALL
在最后执行,因此每个查询都会有重复的行。
Union 和 Union all 的区别在于 Union all 不会消除重复行,
第一个查询输出:
步骤1:
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION All SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
结果 2 行,因为 union all 允许重复。
步骤2:
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
此查询将仅从上述 2 行及其本身中选择没有重复项的行。 返回 1 行。
在第二个查询中...
步骤1
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
返回 1 行,因为 union 仅选择不同的行。
步骤2
UNION ALL SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
返回 2 行,因为它允许重复。
union 和 union 都具有与操作相同的优先级。因此,在没有括号的情况下,您的两个并集将从上到下进行评估。 您的第一个查询的评估如下:
SELECT Name, Marks
FROM
(
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
UNION All
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
) t
UNION
SELECT 'Jack' AS Name, 100 AS Marks FROM DUAL
同样的推理适用于您的第二个查询。
要理解这种行为,您需要清楚 UNION 和 UNION ALL 之间的区别。
查询1:前两行的输出将返回2行。但是,带有“UNION”运算符的最后一行(sql 语句)将删除重复的行,包括它自己的输出。因此,第一个查询总共只会返回 1 行。
查询 2:现在 UNION 位于第二行。与第一行合并后,它将再次仅返回 1 行。但是,在第三行使用“UNION ALL”,它将返回 2 行。因为,“UNION ALL”不会删除重复项。