UNION加入两个结果并删除重复项,而UNION ALL不删除重复项。 UNION也排序最终输出。Sql Union所有*带*“不同”
我想要的是没有重复和没有排序的UNION ALL。那可能吗?
这样做的原因是我希望第一个查询的结果位于最终结果的顶部,而第二个查询的结果位于底部。 (以及每个分类就好像他们在那里单独运行)
UNION加入两个结果并删除重复项,而UNION ALL不删除重复项。 UNION也排序最终输出。Sql Union所有*带*“不同”
我想要的是没有重复和没有排序的UNION ALL。那可能吗?
这样做的原因是我希望第一个查询的结果位于最终结果的顶部,而第二个查询的结果位于底部。 (以及每个分类就好像他们在那里单独运行)
我注意到这个问题得到了相当多的意见,让我我会先问你一个问题没问问!
关于标题。为了实现“Sql 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
+1暴露的排序顺序给调用者是很好的做法,无论如何被删除。 – onedaywhen
@onedaywhen - 感谢您的编辑。错过了这个问题。 –
如果消除单个查询中的重复内容是所有必需的,但这种方法可行,但如果还需要删除两个查询中的重复内容,则不适用。 –
的排序是用来消除重复,并且是隐含的DISTINCT
和UNION
查询(但不是UNION ALL
) - 你仍然可以指定列,你更愿意订购如果你需要他们按特定列排序。
例如,如果你想在结果集进行排序,你可以通过先介绍一个附加列,和排序:
SELECT foo, bar, 1 as ResultSet
FROM Foo
WHERE bar = 1
UNION
SELECT foo, bar, 2 as ResultSet
FROM Foo
WHERE bar = 3
UNION
SELECT foo, bar, 3 as ResultSet
FROM Foo
WHERE bar = 2
ORDER BY ResultSet
我假设你的表分别为表1和表2, 和你的解决方案是;
(select * from table1 MINUS select * from table2)
UNION ALL
(select * from table2 MINUS select * from table1)
这会不会排除有重复的所有行?我宁愿他们想要删除重复的东西! – onedaywhen
看到我的答案进行了更正(我使用的是标准SQL的“EXCEPT”而不是Oracle的“MINUS”,但这不是修正:) – onedaywhen
“UNION还对最终输出进行排序” - 仅作为实现工件。它是由决不意味着保证执行排序,如果你需要一个特定的排序顺序,你应该指定它与ORDER BY
子句。否则,输出顺序是服务器提供的最方便的。
因此,您对执行UNION ALL
但删除重复项的函数的请求很容易 - 它被称为UNION
。
从你澄清,你似乎也相信UNION ALL
将在随后的查询结果返回之前所有的结果从第一查询。这是也不能保证。同样,实现特定顺序的唯一方法是使用ORDER BY
子句来指定它。
SELECT *, 1 AS sort_order
FROM table1
EXCEPT
SELECT *, 1 AS sort_order
FROM table2
UNION
SELECT *, 1 AS sort_order
FROM table1
INTERSECT
SELECT *, 1 AS sort_order
FROM table2
UNION
SELECT *, 2 AS sort_order
FROM table2
EXCEPT
SELECT *, 2 AS sort_order
FROM table1
ORDER BY sort_order;
但真正的答案是:比ORDER BY
条款等,排序顺序将由任意的,不能保证。
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
考虑这些表(标准SQL代码,运行SQL Server 2008上):
WITH A
AS
(
SELECT *
FROM (
VALUES (1),
(2),
(3),
(4),
(5),
(6)
) AS T (col)
),
B
AS
(
SELECT *
FROM (
VALUES (9),
(8),
(7),
(6),
(5),
(4)
) AS T (col)
), ...
所需的效果是这样的由col
升序排序表B
通过col
排序表A
,降则unioning二,删除重复,工会之前保持秩序,在“顶”上的“底部”,例如与表B
离开表A
结果(04-0030-03代码)
(
SELECT *
FROM A
ORDER
BY col
)
UNION
(
SELECT *
FROM B
ORDER
BY col DESC
);
当然,这不会在SQL工作,因为只能有一个ORDER BY
子句和它只能被应用于顶层表表达式(或任何一个SELECT
查询的输出被称为;我称之为“结果集”)。
首先要解决的是两个表格之间的交集,在这种情况下,值为4
,5
和6
。如何对交叉点进行排序需要在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
之前应用。结论显然是因为每个表的排序顺序必须明确通过暴露排序顺序列(S)是联合在一起之前定义。为此,我们可以使用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;
1,1: select 1 from dual union all select 1 from dual
1: select 1 from dual union select 1 from dual
尽管此代码片段是受欢迎的,并且可能会提供一些帮助,如果它包含* how *的解释](// meta.stackexchange.com/q/114762),则说明问题。没有这些,你的答案就没有什么教育价值了 - 记住,你正在为将来的读者回答这个问题,而不仅仅是现在问的人!请编辑您的答案以添加解释,并指出适用的限制和假设。 –
什么SQL供应商是这样吗?我不认为该标准要求'UNION ALL'排序任何东西 - 其实事实上,它不排序,通常是什么使得它比普通'UNION' – Romain
@MikaelEriksson一个更好的选择:这是什么OP说(尽管是在一个混乱的秩序)。他想做一个联盟,但没有隐含的排序。 – mwan
@mwan - 你说得对。我误解了这个问题。 –