2011-01-24 1 views
13

カンマを使用して複数のテーブルを選択できるので、なぜLEFT JOINを使用する必要があるのか​​不思議です。カンマ(、)を使用して複数のテーブルに結合または選択します。

LEFT JOINとカンマを使用して複数の表を選択する方法の違いは何ですか?

どちらが速いのですか?

SELECT mw.*, 
      nvs.* 
    FROM mst_words mw 
LEFT JOIN (SELECT no as nonvs, 
        owner, 
        owner_no, 
        vocab_no, 
        correct 
      FROM vocab_stats 
      WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0) 
     AND mw.level = 1 

...と::ここでは

は私のコードで参加ロジックはできないとしてWHEREからJOINを分離

SELECT * 
    FROM vocab_stats vs, 
     mst_words mw 
WHERE mw.no = vs.vocab_no 
    AND vs.correct > 0 
    AND mw.level = 1 
    AND vs.owner = 1111 
+1

最初はOUTER(この場合はLEFT)JOINの例(ANSI-92)です。後者はINNER JOIN(ANSI-89、OUTER結合をサポートしていません)です。 2つのテーブルをリンクするレコードが常にない限り、同じ結果を返すことはありません。 –

+0

@OMG後者はINNER JOINではありません。それはデカルト積であるので、定義によってクロスジョイントに近い。 – RichardTheKiwi

+1

ANSI-89構文...実行計画は、 '... FROM VOCAB_STATS s MSTWORDS w ON w.no = v.vocab_no ...'を使用するのと同じです。再度 - **いいえ、2番目のクエリはデカルト積を返さない**。 –

答えて

3

まず、完全に同等であることを、最初のクエリは、だから、MW

SELECT mw.*, 
      nvs.* 
    FROM mst_words mw 
LEFT JOIN (SELECT * 
      FROM vocab_stats 
      WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0) 
     AND mw.level = 1 

を書かれている必要があります*とNVS *一緒に同じセットを生成します。これは、より良い例です。 2番目のクエリの単数形*。あなたが書いたクエリは、nvs.correctにフィルタを含んでいるので、INNER JOINを使うことができます。

条件に基づいて、TableBのレコードを見つけるための一般的な形式

TABLEA LEFT JOIN TABLEB ON <CONDITION> 

attempts。失敗した場合、TableAの結果は保持され、TableBのすべての列はNULLに設定されます。コントラスト

TABLEA INNER JOIN TABLEB ON <CONDITION> 

attemptsで条件に基づいて、TableBのレコードを検索します。 が失敗すると、TableAの特定のレコードが出力結果セットから削除されます。

CROSS JOINのANSI標準では、2つのテーブルの間にCartesian productが生成されます。

TABLEA CROSS JOIN TABLEB 
    -- # or in older syntax, simply using commas 
TABLEA, TABLEB 

構文の意図はTABLEAの各行はTABLEBの各行に結合されることです。 Aの4行とBの3行は12行の出力を生成します。 WHERE句の条件と組み合わされると、INNER JOINと同じ動作をします(AとBの間の条件=>保持かどうか)。しかし、カンマの代わりにINNER JOINを使用するときは、意図を読み込むとかなり明確になります。

ほとんどのDBMSは、LEFT結合をINNER JOINより速く処理します。カンマ表記により、データベースシステムは意図を誤って解釈し、不正なクエリプランを生成する可能性があります.SQL92表記の場合も同様です。

なぜLEFT JOINが必要ですか?上記のLEFT JOINの説明ではまだ十分ではない場合(B内の一致がないAのレコードを保持する)、同じことを達成するためには、古いコンマ表記を使用して2つのセット間に複雑なUNIONが必要です効果。 しかし、先に述べたようには、あなたの例には当てはまりません。これは実際にはLEFT JOINの背後に隠れているINNER JOINです。

  • RIGHTは、左右の結合代わりA.
  • のそれはTABLEB(右側)から始まることを除き、LEFTと同じであるが、外部結合共にJOIN。単語OUTERは任意であり、すなわちLEFT OUTER JOINと書くことができる。
  • 3番目のタイプのOUTER結合はFULL OUTER結合ですが、ここでは説明しません。
0

は、読みが容易になりますWHERE条件と混同しないでください。また、サーバーは2つの個別のクエリを実行して結果を結合する必要がないため、一般的に高速になります。

最初の例でサブクエリを含めたので、あなたが与えた2つの例は実際には同等ではありません。 、すべての

SELECT vs.*, mw.* 
FROM vocab_stats vs, mst_words mw 
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no 
WHERE vs.correct > 0 
AND mw.level = 1 
AND vs.owner = 1111 
+0

SQLが無効です – RichardTheKiwi

+0

ありがとう、私は誤植を削除しました。 – Bazmatiq

関連する問題