この例に出くわしましたが、その意味がわかりません。
(SELECT drinker FROM Frequents)
EXCEPT ALL
(SELECT drinker FROM Likes);
関係: 常連 (酒飲み、バー)、好き (酒飲み、ビール)
この場合、ALL は何をしますか? 結果は以下のクエリとどのように異なりますか?
(SELECT drinker FROM Frequents)
EXCEPT
(SELECT drinker FROM Likes);
この例に出くわしましたが、その意味がわかりません。
(SELECT drinker FROM Frequents)
EXCEPT ALL
(SELECT drinker FROM Likes);
関係: 常連 (酒飲み、バー)、好き (酒飲み、ビール)
この場合、ALL は何をしますか? 結果は以下のクエリとどのように異なりますか?
(SELECT drinker FROM Frequents)
EXCEPT
(SELECT drinker FROM Likes);
SQL EXCEPT 演算子は、1 つのクエリの個別の行を取得し、2 番目の結果セットに表示されない行を返します。EXCEPT ALL 演算子は重複を削除しません。行の削除と重複の削除のために、EXCEPT 演算子は NULL を区別しません。
EXCEPT ALL は、2 番目のテーブルに存在しない最初のテーブルのすべてのレコードを返し、重複をそのまま残します。残念ながら、SQL Server はこの演算子をサポートしていません。
私は最近INTERSECT ALLとEXCEPT ALLを実装しましたが、SOにはあまりリソースがないことがわかりました。
次のデータの例を考えてみましょう。
sqlfiddle.comで例を再現できます。postgres 9.3 を使用してください。一般的なデータベースのほとんどはINTERSECT ALLとEXCEPT ALL
を
サポートしていないことに注意してください。を使用した回避策はもちろん可能です。row_number() over ()
create table x (V1 numeric);
create table y (V1 numeric);
insert into x values (1),(2),(2),(2),(3),(4),(4);
insert into y values (2),(3),(4),(4),(4),(5);
EXCEPT [ALL]は、両方のテーブルのすべての列で一致し、列の型と順序が一致する必要があります。
select * from x except select * from y;
| v1
----
| 1
select * from x except all select * from y;
| v1
----
| 1
| 2
| 2
EXCEPT sql プロセスでは個別のデータセットが処理されるため、重複は自動的に削除され、各行の単一のコピーのみが残ります。これにより、2 番目のデータセットの行に 1 つだけ一致することに基づいて行が除外されます。
一方、EXCEPT ALLは、重複する行数を考慮してデータセットを処理します。これにより、テーブル間の重複行の正確な違いが返されます。まさにmax(0, x.N - y.N)。
EXCEPT ALLによく似た別のトリッキーな演算子はINTERSECT ALLmin(x.N, y.N)です。これは、一致する各行の複製を 返します。
私がコミットしたプロジェクトはこの機能がオープンソースであるため、ここにリンクを掲載できることをうれしく思います: github.com/Rdatatable/data.table。ベンチマークするツールを探す場合に役立つ場合があります。data.tableインメモリであり、ほとんどがCで実装されたデータ処理です。すでに約 10 年前にオープンソース化されています。