まず、完全に同等であることを、最初のクエリは、だから、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結合ですが、ここでは説明しません。
最初はOUTER(この場合はLEFT)JOINの例(ANSI-92)です。後者はINNER JOIN(ANSI-89、OUTER結合をサポートしていません)です。 2つのテーブルをリンクするレコードが常にない限り、同じ結果を返すことはありません。 –
@OMG後者はINNER JOINではありません。それはデカルト積であるので、定義によってクロスジョイントに近い。 – RichardTheKiwi
ANSI-89構文...実行計画は、 '... FROM VOCAB_STATS s MSTWORDS w ON w.no = v.vocab_no ...'を使用するのと同じです。再度 - **いいえ、2番目のクエリはデカルト積を返さない**。 –