今日、より複雑なMySQLクエリをいくつか試しましたが、MySQLのLEFT JOINがWHERE句で機能していないことに気付きました。つまり、一部のレコードは返されますが、右側が空のレコードは返されません。
たとえば、テーブルがあるとします。
アルバム; albums_rap idアーティストタイトルトラック; idアーティストタイトルランク ---- -------- ---------- ---------------; ---- --------- ----- -------------- 1 John Doe Mix CD 20; 3マークCD#7 15 2マークCD#7 35;
そして、私がこのクエリを実行すると:
SELECT
t1.artist as artist,
t1.title as title,
t1.tracks as tracks,
t2.rank as rank,
FROM
albums as t1
LEFT JOIN
albums_rap as t2
ON
t1.artist LIKE t2.artist
AND
t1.title LIKE t2.title
WHERE
t2.rank != 17
私はこれを手に入れます:
アーティストタイトルトラックランク ------ ----- ------ ----- Mark CD#7 35 15
しかし、このクエリで「WHERE」を「AND」に置き換えると、次のようになります。
アーティストタイトルトラックランク ------ --------- ------ ----- Mark CD#7 35 15 John Doe Mix CD 20 NULL
最初のレコードが「NULL」のレコードを返さない理由(nullは17と等しくない...)
あなたが私が何を言っているのか理解していただけたら幸いです。どういうわけか私に違いを説明してください。英語が下手で申し訳ありませんが、母国語ではありません。
左結合条件とwhere条件フィルターはどちらも同じではありません。物理的な結合が行われた後、データはwhere句によってフィルタリングされます。左側の結合を見ると、通常は左側のテーブルからすべての行が返されますが、where句を指定すると、結合の出力がフィルタリングされるため、結果は内部結合のようになります。下の画像の左側にある2つの図に注目してください。
最初のケース:
結合後、レコードは(WHERE句)によってフィルタリングされます。したがって、結果は1つだけです。
2番目のケース(WHEREをANDに置き換えた場合)
すべての結合エントリと2番目の条件(t2.rank!= 17)で満たされたエントリを返します。そのため、ここでは2つのレコードを取得しています(1つは結合から、もう1つはAND句から)
この質問に対する解決策は、SQLステートメントの実行順序または論理クエリ処理フェーズを理解すると、非常に直感的になります。順序は:-
1. FROM
2. ON
3. OUTER
4. WHERE
5. GROUP BY
6. CUBE | ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP
JOINのOUTER(LEFT/RIGHT)部分(NULL値の行を追加)の前にONが実行されるため、1番目のケースでは、ランク列にNULL値の行があります。 2番目のケースでは、OUTER JOIN(ここではLEFT JOIN)が実行された後、行がランク列の値に基づいてフィルターで除外されます。したがって、ランク列にNULL値を含む行は除外されます。
SQLクエリで気づくことができる1つの非常に重要なことは、NULLとの比較ですこの領域は、NULL/NON-の場合、NULL値として特別な注意が必要です通常の算術演算子を使用したNULL値は、比較に使用できる値がないことを意味するため、NULL(TRUEでもFALSEでもない)になります。この動作はANSI SQL-92標準で定義されています。(これは、一部のSQLでansi null(実際の名前は異なる場合があります)パラメータをオフにすることでオーバーライドできます。プロセッサ)したがって、where句を使用したSQLクエリは、「17!= NULL」が原因で直感に反する可能性があるため、ランク列にNULL値を含む行を除外します。
NULL = NULLはNULL/UNKNOWNを返します
17 = NULLはNULL/UNKNOWNを返します
17!= NULLの結果NULL?UNKNOWN
参考になる興味深い投稿/ブログは次のとおりです。
http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/http:/ /blog.sqlauthority.com/2009/03/15/sql-server-interesting-observation-of-on-clause-on-left-join-how-on-clause-effects-resultset-in-left-join/http://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
「LEFT JOINキーワードは、左側のテーブル(table1)からすべての行を返し、右側のテーブル(table2)の一致する行を使用します。一致がない場合、結果は右側でNULLになります。 。」
上記の引用は w3schools.com からのものです
ただし、WHERE句をLEFT JOINに配置すると、SQLはそれをINNER JOINとして扱い、次のようになります。
「両方のテーブルの列が一致する限り、INNER JOINキーワードは両方のテーブルからすべての行を選択します。」
w3schools.com からも引用
TLDR;
LEFT OUTER JOINへのWHERE句の導入により、結合にINNER JOINの動作が与えられます