如何不排序就执行UNION? (SQL)

问题描述 投票:35回答:10

UNION合并两个结果并删除重复项,而UNION ALL则不删除重复项。UNION还会对最终输出进行排序。

我想要的是UNION ALL,没有重复,也没有排序。有可能吗?

原因是我希望第一个查询的结果位于最终结果的顶部,第二个查询在底部(并且每个查询的排序方式都好像它们分别在运行)。

sql union distinct union-all
10个回答
48
投票
没有提出的问题!

关于标题。要实现“ Sql Union All with“ distinct””,只需将UNION ALL替换为UNION。这具有删除重复项的效果。

对于您的特定问题,给出的澄清是“您可以使用第一个查询的优先级,因此应该从底部删除重复项”

SELECT col1, col2, MIN(grp) AS source_group FROM (SELECT 1 AS grp, col1, col2 FROM t1 UNION ALL SELECT 2 AS grp, col1, col2 FROM t2) AS t GROUP BY col1, col2 ORDER BY MIN(grp), col1

10
投票
no手段保证可以执行排序,如果需要特定的排序顺序,则应使用ORDER BY子句指定它。否则,输出顺序是服务器最方便提供的顺序。

因此,您对执行UNION ALL但删除重复项的函数的请求很容易-称为UNION

根据您的说明,您似乎还认为UNION ALL将返回第一个查询的所有结果,而不返回后续查询的结果。这也不保证。同样,实现特定顺序的唯一方法是使用ORDER BY子句指定该顺序。


3
投票

3
投票
[期望的效果是按A升序对表col进行排序,按B降序对表col进行排序,然后将两者合并,删除重复项,在合并之前保留顺序,并保留表A的结果“底部”中带有表B的“顶部”,例如(伪代码)

( SELECT * FROM A ORDER BY col ) UNION ( SELECT * FROM B ORDER BY col DESC );

当然,这在SQL中不起作用,因为只能有一个ORDER BY子句,并且它只能应用于顶级表表达式(或SELECT查询的任何输出被称为;我称其为“结果集”。

首先要解决的是两个表之间的交集,在这种情况下,值为456。需要在SQL代码中指定应如何对相交进行排序,因此,设计人员也希望对此进行指定! (在这种情况下,就是问这个问题的人)。

在这种情况下,似乎意味着相交(“重复项”)应在表A的结果内排序。因此,排序后的结果集应如下所示:

VALUES (1), -- A including intersection, ascending (2), -- A including intersection, ascending (3), -- A including intersection, ascending (4), -- A including intersection, ascending (5), -- A including intersection, ascending (6), -- A including intersection, ascending (9), -- B only, descending (8), -- B only, descending (7), -- B only, descending

在SQL中,“ top”和“ bottom”的注释没有推断的含义,并且表(结果集除外)没有固有的顺序。另外(简而言之,)请考虑UNION隐式删除重复的行,并且必须在ORDER BY之前应用。结论是必须通过暴露要合并的排序顺序列来明确定义每个表的排序顺序。为此,我们可以使用ROW_NUMBER()窗口函数,例如

... A_ranked AS ( SELECT col, ROW_NUMBER() OVER (ORDER BY col) AS sort_order_1 FROM A -- include the intersection ), B_ranked AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY col DESC) AS sort_order_1 FROM B WHERE NOT EXISTS ( -- exclude the intersection SELECT * FROM A WHERE A.col = B.col ) ) SELECT *, 1 AS sort_order_0 FROM A_ranked UNION SELECT *, 2 AS sort_order_0 FROM B_ranked ORDER BY sort_order_0, sort_order_1;

select T.Col1, T.Col2, T.Sort from ( select T.Col1, T.Col2, T.Sort, rank() over(partition by T.Col1, T.Col2 order by T.Sort) as rn from ( select Col1, Col2, 1 as Sort from Table1 union all select Col1, Col2, 2 from Table2 ) as T ) as T where T.rn = 1 order by T.Sort


1
投票
尝试一下:

1
投票

排序用于消除重复项,对于DISTINCTUNION查询(但不是UNION ALL)是隐式的-如果您需要按排序方式对列进行排序,则仍然可以指定特定列。


0
投票

我假设您的表分别是table1和table2,而您的解决方案是;


0
投票

1,1: select 1 from dual union all select 1 from dual 1: select 1 from dual union select 1 from dual


-1
投票
您可以做这样的事情。
© www.soinside.com 2019 - 2024. All rights reserved.