Sql Union All * with *“distinct”

时间:2011-09-26 07:47:52

标签: sql union distinct union-all

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

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

这样做的原因是我希望第一个查询的结果位于最终结果之上,而第二个查询位于底部。 (并且每个分类就像它们单独运行一样)

9 个答案:

答案 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查询的输出。被称为;我称之为“结果集”。)

要解决的第一件事是两个表之间的交集,在这种情况下是值456。需要在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)

排序用于消除重复项,并且隐含于DISTINCTUNION个查询(但不是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;