36

UNION2つの結果を結合して重複を削除しますが、重複UNION ALLは削除しません。
UNIONまた、最終出力を並べ替えます。

私が欲しいのは、UNION ALL重複や並べ替えがないことです。それは可能ですか?

これは、最初のクエリの結果を最終結果の上に置き、2番目のクエリを一番下に配置する(そしてそれぞれが個別に実行されるかのように並べ替える)ためです。

4

10 に答える 10

52

この質問は非常に多くの意見を集めていることに気付いたので、最初にあなたが尋ねなかった質問に取り組みます!

タイトルについて。「SQLUnionAllwith “ 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  
于 2011-09-26T07:56:36.310 に答える
11

「UNIONは最終出力もソートします」-実装アーティファクトとしてのみ。ソートの実行は保証されていません。特定のソート順が必要な場合は、ORDER BY句を指定して指定する必要があります。それ以外の場合、出力順序はサーバーが提供するのに最も便利なものです。

そのため、を実行するUNION ALLが重複を削除する関数のリクエストは簡単です。これはと呼ばれUNIONます。


UNION ALLあなたの説明から、あなたはまた、aが後続のクエリの結果の前に最初のクエリからのすべての結果を返すと信じているように見えます。これ保証されません。繰り返しますが、特定の順序を実現する唯一の方法は、ORDER BY句を使用してそれを指定することです。

于 2011-09-26T07:59:05.983 に答える
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)
     ), ...

望ましい効果は、テーブルAcol昇順で並べ替え、テーブルBcol降順で並べ替えてから2つを結合し、重複を削除し、結合前の順序を保持し、テーブルのA結果を「上」に残し、テーブルBを「下」に残すことです。例:(疑似コード)

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

もちろん、これはSQLでは機能しません。これは、ORDER BY句が1つしかなく、最上位のテーブル式(または、SELECTクエリの出力として知られているもの、つまり「結果セット」)にのみ適用できるためです。

最初に対処するのは、2つのテーブル(この場合は値45および)の共通部分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。結論として、各テーブルのソート順は、結合される前にソート順列を公開することによって明示的に定義する必要があります。このために、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;
于 2011-09-26T13:11:33.597 に答える
3
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句を除いて、並べ替え順序は任意であり、保証されません。

于 2011-09-26T08:14:03.670 に答える
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
于 2011-09-26T08:22:02.733 に答える
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
于 2019-02-27T07:17:51.777 に答える
0

私はあなたのテーブルがそれぞれtable1とtable2であると仮定し、あなたの解決策は;

(select * from table1 MINUS select * from table2)
UNION ALL
(select * from table2 MINUS select * from table1)
于 2011-09-26T07:57:49.273 に答える
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
于 2011-09-26T07:53:56.727 に答える
-1

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

于 2017-05-08T09:27:48.627 に答える
-1

あなたはこのようなことをすることができます。

Select distinct name from  (SELECT r.name FROM outsider_role_mapping orm1 
    union all
SELECT r.name FROM user_role_mapping orm2
) tmp;
于 2019-01-04T14:09:01.723 に答える