2012-09-13 6 views
18

SQL-Anweisung.Unterschied zwischen "on .. and" und "on .. wo" in SQL Left Join?

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; 

Was ist der Unterschied dieser beiden SQL-Anweisung?

+1

http://stackoverflow.com/questions/10297231/where-clause-vs-on-when-using-join – Habib

+4

Nicht ein Duplikat, 'LEFT JOIN' hier signifikant ändert die Frage. – hvd

+1

@hvd - die Fragen sind vielleicht nicht exakt Duplikate, aber da die meisten Antworten im Sinne von "es ist egal für" INNER JOIN ", aber hier wäre was anders für" OUTER JOIN's ... " –

Antwort

23
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 

Filter auf der JOIN-Reihen zu verhindern, dass während des Prozesses JOIN hinzugefügt wird.

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 wird gefiltert, nachdem der JOIN aufgetreten ist.

select a.*,b.* 
from A a left join B b 
on  a.id =b.id 
where a.id=2; 

id   id 
----------- ----------- 
2   2 
+0

Danke für dein Detail, erklären –

+0

@ jack.li froh um Ihnen zu helfen :) –

+0

Aus irgendeinem Grund funktionierte es nicht wie erwartet in diesem sqlfiddle: http://sqlfiddle.com/#!2/9684d/4 Aber wenn ich es in MySQL versuchte, funktionierte es genau wie Sie sagten. –

8

Wählen Sie a. * Von A eine linke Verknüpfung B b auf a.id = b.id und a.id = 2;

Dies nutzt nur a.id in der Join-Bedingung, so Datensätze, bei denen a.id <> 2 heraus werden nicht gefiltert. Sie könnten ein Ergebnis wie folgt erhalten:

 
+------+------+ 
| a.id | b.id | 
+------+------+ 
| 1 | NULL | 
| 2 | 2 | 
| 3 | NULL | 
+------+------+ 

du nicht von b ‚s Spalten auswählen, aber wenn Sie das tun, wird es leichter zu verstehen sein.

Wählen Sie a. * Aus A a links B b auf a.id = b.id wobei a.id = 2;

Jetzt Aufzeichnungen, wo a.id <> 2 werden herausgefiltert.

 
+------+------+ 
| a.id | b.id | 
+------+------+ 
| 2 | 2 | 
+------+------+ 
0

Wie @hvd sagt, das „Wo“ -Klausel filtert Zeilen, die von der Verbindung zurückgegeben, so dass die „where“ Version wird nicht zurückkehren Außen verknüpften Zeilen (die haben a.id = null).

Es gibt jedoch einen weiteren signifikanten Unterschied: Selbst wenn die äußeren verbundenen Zeilen nicht ausgefiltert wurden, kann es einen massiven Leistungsschub geben, indem die Bedingung in die "on" -Klausel gesetzt wird, weil die Ergebnismenge früher kleiner gemacht wird. Das ist besonders ausgeprägt, wenn eine Reihe von anderen linksverbundenen Tabellen denen mit der Bedingung "und" folgt - Sie können verhindern, dass Joins mit den folgenden Tabellen für ungeeignete Zeilen überhaupt passieren und möglicherweise Millionen von Zeilen davon abhalten, die Zeilen zu erreichen Filtern ("wo") Bühne.

0

Ich versuche einige Zeit, und ich weiß, was der Grund ist, bezieht es sich nur auf eine Priorität.

select * from A a left join B b on a.id=b.id and b.id=2 

dies bedeutet eine linke verbinden (wobei b.id = 2) Dies ist die Bedingung Filter B zuerst

Select * from A a left join B b on a.id=b.id where a.id=2 

dieses B verbinden Einrichtung, nachdem das Filter dann durch a.id = 2

0

Wenn Sie über die Syntax einer SQL-Abfrage nachdenken, erweitert das 'AND' den Join-Block (wie bei Klammern), während 'WHERE' den Beginn des WHERE-/Filterblocks der Abfrage definiert.

Verwandte Themen