SQLステートメント。
1.select a.* from A a left join B b on a.id =b.id and a.id=2;
2.select a.* from A a left join B b on a.id =b.id where a.id=2;
この2つのSQLステートメントの違いは何ですか?
create table A(id int);
create table B(id int);
INSERT INTO A VALUES(1);
INSERT INTO A VALUES(2);
INSERT INTO A VALUES(3);
INSERT INTO B VALUES(1);
INSERT INTO B VALUES(2);
INSERT INTO B VALUES(3);
SELECT * FROM A;
SELECT * FROM B;
id
-----------
1
2
3
id
-----------
1
2
3
JOINでフィルタリングして、JOINプロセス中に行が追加されないようにします。
select a.*,b.*
from A a left join B b
on a.id =b.id and a.id=2;
id id
----------- -----------
1 NULL
2 2
3 NULL
WHEREは、JOINが発生した後にフィルタリングします。
select a.*,b.*
from A a left join B b
on a.id =b.id
where a.id=2;
id id
----------- -----------
2 2
select a.* from A a left join B b on a.id =b.id and a.id=2;
a.id
これは結合条件でのみ使用されるため、レコードはa.id <> 2
除外されません。次のような結果が得られる場合があります。
+--------+------+ | | a.id | b.id | +--------+------+ | | 1 | ヌル | | | 2 | 2 | | | 3 | ヌル | +--------+------+
の列は選択していませんが、選択するb
と理解しやすくなります。
select a.* from A a left join B b on a.id =b.id where a.id=2;
a.id <> 2
除外される場所を記録するようになりました。
+--------+------+ | | a.id | b.id | +--------+------+ | | 2 | 2 | +--------+------+
@hvdが言うように、"where" 句は結合によって返される行をフィルター処理するため、"where" バージョンは外部結合された行 (a.id = null を持つ) を返しません。
ただし、もう 1 つの重要な違いがあります。外部結合された行が除外されていない場合でも、条件を「on」句に入れるとパフォーマンスが大幅に向上する可能性があります。これは、結果セットが以前に小さくなったためです。
これは、一連の他の左結合されたテーブルが「and」条件を持つテーブルの後に続く場合に特に顕著です。不適切な行のために後続のテーブルに結合が発生することさえ防ぎ、フィルタリングに到達する何百万もの行を切り落とす可能性があります ("where ")ステージ。
SQL クエリの構文について考えると、'AND' は結合ブロックを拡張し (where 括弧のように)、'WHERE' はクエリの WHERE/フィルタリング ブロックの開始を定義します。
私はしばらく試してみましたが、その理由はわかっています。それは優先順位にのみ関連しています。
select * from A a left join B b on a.id=b.id and b.id=2
これは A left join (b.id=2 の場合) を意味します これは条件フィルター B first です
Select * from A a left join B b on a.id=b.id where a.id=2
これは、B に参加した後、a.id=2 でフィルタリングすることを意味します