2017-02-17 22 views
1

私はSOから多くの投稿を読みました。where節とon節のフィルタリングの違いを理解しています。しかし、これらの例のほとんどは、RIGHTテーブルのフィルタリングです(左結合を使用する場合)。次のようなクエリがある場合:SQLフィルタleft left join before left join

select * from tableA A left join tableB B on A.ID = B.ID and A.ID = 20 

戻り値は私が期待したものではありません。私はそれが最初に左のテーブルをフィルタリングし、ID = 20の行だけを取り出し、次にtableBとの左の結合を行います。もちろん

、これは技術的にやってと同じでなければなりません:

select * from tableA A left join table B on A.ID = B.ID where A.ID = 20 

をしかし、私は、あなたが参加を実行する前にテーブルをフィルタリングすることができればパフォーマンスが良いだろうと思いました。誰かがこのSQLがどのように処理されているかについて私に啓発し、これを完全に理解するのに役立ちますか? (Xを選択します。* x.value = 20 TABLEA Xから)からのようにあなたがTABLEAから持って

答えて

3

left joinは、単純なルールに従う。最初のテーブルにすべての行が保持されます。 の値は、on句に依存します。一致するものがない場合、対応する表の列はNULL - 最初の表か2番目の表かになります。

ので、このクエリに対して:

select * 
from tableA A left join 
    tableB B 
    on A.ID = B.ID and A.ID = 20; 

Aのすべての行にかかわらず、一致があるかどうかの、結果セットです。 idが20でない場合、行と列は依然としてAから取得されます。ただし、条件はfalseなので、Bの列はNULLです。これは単純なルールです。条件が最初のテーブルか2番目のテーブルかに依存しません。このクエリの

select * 
from tableA A left join 
    tableB B 
    on A.ID = B.ID 
where A.ID = 20; 

from句がAのすべての行を保持します。しかし、where句がその効果を持ちます。そして、それは結果セット内のid 20sだけで行をフィルタリングします。left joinを使用して

  • フィルタ条件を最初のテーブルの上にはwhere句に行きます。
  • 以降の表のフィルタ条件は、on節に記載されています。
+0

お返事ありがとうございますが、 "idが20でない場合は、列の値はNULLです"ということを詳しく説明することができます。 tableBのIDが20でないことを意味しますか?それからtableBのすべての列はnullになりますか?これにはユースケースがありますか?または、最初のテーブルのフィルタリングは常にwhere句に移動する必要がありますか? – TFK

+0

@TFK。 。 。私はフレーズを修正した。 –

0

は、あなたがサブクエリを置くことができ、あなたが以前にTABLEAを行ったようにTA

が続いてTAを参照してください。

クエリオプティマイザがこれを行う可能性があります。

Oracleには、クエリプランを表示する方法があります。 SQL文の前に "Explain plan"を入れてください。両方の方法で計画を見て、それが何を参照してください。

+0

論理的には正しいですが、オプティマイザはそのように書き換えません。それはOUTER JOIN演算子です。 – BobC

0

最初のSQL文では、A.ID=20は技術的に何かに結合されていません。結合は、2つの別個の表を一緒に接続するために使用され、ON文は列をキーとして関連付けることによって結合します。

WHEREステートメントは、その特定の列の下にその値が見つかる場所でのみ返される行の数を減らすことで、データのフィルタリングを可能にします。