UNION加入两个结果并删除重复项,而UNION ALL不会删除重复项。 UNION还对最终输出进行排序。
我想要的是没有重复且没有排序的UNION ALL。这可能吗?
这样做的原因是我希望第一个查询的结果位于最终结果之上,而第二个查询位于底部。 (并且每个分类就像它们单独运行一样)
答案 0 :(得分:47)
我注意到这个问题得到了很多观点,所以我首先要解决你没有问的问题!
关于标题。要实现“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
答案 1 :(得分:10)
“UNION也对最终输出进行排序” - 仅作为实现工件。保证执行排序 no not ,如果需要特定的排序顺序,则应使用ORDER BY
子句指定它。否则,输出顺序是服务器最方便的输出顺序。
因此,您对执行UNION ALL
但删除重复项的函数的请求很容易 - 它被称为UNION
。
从您的澄清中,您似乎也相信UNION ALL
将在后续查询结果之前返回第一个查询的所有结果。这也无法保证。同样,实现特定顺序的唯一方法是使用ORDER BY
子句指定它。
答案 2 :(得分:3)
考虑这些表(标准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)
), ...
所需的效果是按A
升序排序表col
,按B
降序排序表col
然后合并两者,删除重复项,保留顺序联合和离开表A
结果在“顶部”上,表格B
位于“底部”,例如(pesudo代码)
(
SELECT *
FROM A
ORDER
BY col
)
UNION
(
SELECT *
FROM B
ORDER
BY col DESC
);
当然,这在SQL中不起作用,因为只能有一个ORDER BY
子句,它只能应用于顶级表表达式(或SELECT
查询的输出。被称为;我称之为“结果集”。)
要解决的第一件事是两个表之间的交集,在这种情况下是值4
,5
和6
。需要在SQL代码中指定如何对交集进行排序,因此设计人员也希望对此进行指定! (即提问的人,在这种情况下)。
在这种情况下的含义似乎是交集(“duplicates”)应该在表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;
答案 3 :(得分:2)
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
子句之外,排序顺序将是任意的而不是保证。
答案 4 :(得分: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
答案 5 :(得分:1)
尝试一下:
SELECT DISTINCT * FROM (
SELECT column1, column2 FROM Table1
UNION ALL
SELECT column1, column2 FROM Table2
UNION ALL
SELECT column1, column2 FROM Table3
) X ORDER BY Column1
答案 6 :(得分:0)
排序用于消除重复项,并且隐含于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
答案 7 :(得分:0)
我假设你的表分别是table1和table2, 你的解决方案是;
(select * from table1 MINUS select * from table2)
UNION ALL
(select * from table2 MINUS select * from table1)
答案 8 :(得分:-1)
您可以执行以下操作。
Select distinct name from (SELECT r.name FROM outsider_role_mapping orm1
union all
SELECT r.name FROM user_role_mapping orm2
) tmp;