6

次のような 2 つのテーブル TABLE1 があります。

id      name     address
1       mm     123
2       nn     143

TABLE2 w/c は次のようになります。

name     age
mm      6
oo      9

TABLE1と を比較して、存在しない名前を取得したいTABLE2

したがって、基本的には 2 行目を取得する必要があります。w/c には に存在しない NN 名がありTABLE2、出力は次のようになります。

id      name     address
2      nn      143

私はこれを試しましたが、うまくいきません:

SELECt  w.* FROM TABLE1 W INNER JOIN TABLE2 V
  ON W.NAME <> V.NAME

そして、それはまだ既存のレコードを取得しています。

4

2 に答える 2

2

必要な関係演算子は、反結合とも呼ばれるセミ差分です

ほとんどの SQL 製品には、明示的な準差分演算子またはキーワードがありません。標準 SQL-92 にはそれがありません (MATCH (subquery)準結合述語がありますが、そうではないと考えたくなるかもしれませんが、 のセマンティクスはNOT MATCH (subquery)半差分と同じではありません。FWIW 真のリレーショナル言語のチュートリアル Dでは半差分をうまく使用していNOT MATCHINGます)。

もちろん、他の SQL 述語を使用して準差分を記述することもできます。最も一般的に見られるのは、WHERE句内の null のテストを伴う外部結合で、すぐ後にEXISTSorが続くものIN (subquery)です。使用するEXCEPT(Oracle と同等MINUS) は、SQL 製品がサポートしている場合、またデータに応じて (具体的には、2 つのテーブルの見出しが同じ場合) 別の可能なアプローチです。

個人的にはEXISTS、結合句が記述されたコードでより近くにあり、結合されたテーブルに対する射影が発生しないため、半差分結合に SQL で使用することを好みます。

SELECT *
  FROM TABLE1 W
 WHERE NOT EXISTS (
                   SELECT * 
                     FROM TABLE2 V
                    WHERE W.NAME = V.NAME
                  );

(外部結合アプローチとNOT IN (subquery)同じ)と同様に、サブクエリ内の句にnullが含まれる場合は特に注意する必要がありますWHERE(ヒント:WHEREサブクエリの句がnullの存在によりUNKNOWNと評価された場合、強制的にFALSEになりますEXISTS、予期しない結果が生じる可能性があります)。


更新(3年後):それ以来、NOT IN (subquery)読みやすくなり、nullの予期しない結果が心配な場合(そうあるべきです)、それらを完全に使用するのをやめたので、優先に切り替えました。

より読みやすい方法の 1 つは、範囲変数の要件がないことです。WたとえばV

SELECT * FROM TABLE1 WHERE name NOT IN ( SELECT name FROM TABLE2 );
于 2011-09-21T07:43:40.717 に答える