UNIONは2つの結果を結合して重複を削除しますが、UNION ALLは重複を削除しません。 UNIONは最終出力もソートします。
私が欲しいのは、重複やソートのないUNION ALLです。それは可能ですか?
その理由は、最初のクエリの結果が最終結果の上になり、2番目のクエリの結果が最後になるようにするためです。 (それぞれが個別に実行されるかのようにソートされます)
この質問には非常に多くの意見がありますので、まず質問に答えますdid n't ask!
タイトルについて。 「Sql Union Allwith“ distinct”」を達成するには、単にUNION ALL
with 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
「UNIONは最終出力もソートします」-実装アーティファクトとしてのみ。 無意味によるソートの実行が保証されています。特定のソート順が必要な場合は、ORDER BY
句で指定する必要があります。それ以外の場合、出力順序はサーバーが提供するのに最も便利なものです。
そのため、UNION ALL
を実行するが重複を削除する関数のリクエストは簡単です。これはUNION
と呼ばれます。
説明から、UNION ALL
が最初のクエリの結果をすべて返し、その後のクエリの結果を返すと信じているようにも見えます。これはalso保証されていません。繰り返しますが、特定の順序を実現する唯一の方法は、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
句、ソート順は任意であり、保証されません。
次の表を考慮してください(標準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
でソートし、降順で2つを結合し、重複を削除し、結合前の順序を保持して終了することです。テーブルA
は "top"に、テーブルB
は "bottom"に、例えば(擬似コード)
_(
SELECT *
FROM A
ORDER
BY col
)
UNION
(
SELECT *
FROM B
ORDER
BY col DESC
);
_
もちろん、これはSQLでは機能しません。なぜなら_ORDER BY
_句は1つしか存在せず、トップレベルのテーブル式(またはSELECT
クエリの出力は;「結果セット」と呼びます)。
最初に対処するのは、2つのテーブルの交差点です。この場合、値は_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の「上」および「下」の注には推論的な意味はなく、テーブル(結果セット以外)には固有の順序はありません。また、(長い話を短くするために)UNION
は含意によって重複行を削除し、_ORDER BY
_の前に適用する必要があることを考慮してください。結論は、各テーブルのソート順は、ソート順列を公開することによって明示的に定義する必要があるということですbefore unionedこのために、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 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
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
ソートは重複を排除するために使用され、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
私はあなたのテーブルがそれぞれtable1とtable2であり、あなたのソリューションがそうであると仮定します;
(select * from table1 MINUS select * from table2)
UNION ALL
(select * from table2 MINUS select * from table1)