2017-07-20 11 views
-2

以下の2つのクエリが異なるカウントをフェッチする理由を理解できません。ケース1はより多くの行をフェッチし、ケース2は少数の行をフェッチします。 where句を外側に置くと、取り出されるレコードが少なくなります。WHERE句を残して行を制限する

ケース1

SELECT COUNT(1) 
FROM (
    SELECT * 
    FROM (SELECT * FROM TABLE1 WHERE COL1 = 123) A 
      LEFT JOIN TABLE2 B ON B.COL2=A.COL4 
      LEFT JOIN TABLE3 C ON C.COL3=B.COL2 
    ) 

ケース2

SELECT COUNT(1) 
FROM (
    SELECT * 
    FROM (SELECT * FROM TABLE1) A 
     LEFT JOIN TABLE2 B ON B.COL2=A.COL4 
     LEFT JOIN TABLE3 C ON C.COL3=B.COL2 
    ) 
WHERE COL1 = 123 
+1

この現象を再現するサンプルデータを掲載してください。 – APC

+0

理論的にはこれは可能ですが、サンプルデータがなければ、結果を説明することは困難です – scaisEdge

+0

返信いただきありがとうございます。しかし、もしあなたが理論的な説明を提供することができますも – zubi

答えて

1

理論的説明:

が表Bの左外側テーブルAとBの結合条件(フィルタ)が異なる有し検討結合条件(ON句)とWHERE句の間にある場合の影響EDIT:ON状態にあるBのフィルタは、Bをフィルタが最初に適用されるサブクエリ(OPの例に似ています)に置き換えることと同等です。

ON句内にある場合、テーブルBの行はその条件でフィルタリングされ、次に左結合が実行されます。フィルタに合致する行がB内になく、結合条件でAの行と一致する場合は、問合せの結果にAからの行(B側はNULL)が含まれます。

一方、Bのフィルタが実行の後に来る場合、WHERE句では左結合が最初に実行されます。そのときだけ、WHERE句が適用されます。 WHERE句は、Bの条件に応じて、Bに一致する行がないAからすべての行を拒否する可能性が非常に高いです。そのような行の場合、Bのすべての値がNULLであるためです。

COL1のみがテーブルBに存在すると仮定すると、WHERE句の条件COL1 = 123は、効果的に左結合が内部結合と同じ結果を生成する原因となります。 Bの一致がCOL1をNULLとして左結合から来るため、フィルタ条件に失敗します。 COL1 = 123をON句に入れると、そのチェックは「外部結合」操作の前に実行されます。

+0

半シュートの説明。テーブル「A」と「B」の使い方がOPを一致させるのではなく、それを反転させた方がいいでしょう。 – APC

+0

@APC - 理論的な説明を求めたので、私は意図的にOPの例を読まなかった。私は最後の段落を追加するつもりはなかったが、私はそれがあまりにも理論的かもしれないと感じた。 – mathguy

+1

@APC - err ...今OPの例を読んで、OPが間違っています。フィルタは左結合の左側の表にあるので、これらの問合せは同じ結果を生成する必要があります。このようなフィルタは、ON句またはWHERE句に入れることができます。違いはありません。私は説明を求めます。 – mathguy

関連する問題