2010-04-27 12 views
34

Le seguenti affermazioni danno lo stesso risultato (si sta usando on, e l'altro utilizzando where):In SQL/MySQL, qual è la differenza tra "ON" e "WHERE" in una dichiarazione di join?

mysql> select * from gifts INNER JOIN sentGifts ON gifts.giftID = sentGifts.giftID; 
mysql> select * from gifts INNER JOIN sentGifts WHERE gifts.giftID = sentGifts.giftID; 

posso vedere solo in un caso di un join esterno sinistro trovando i casi "senza pari":
(per scoprire i doni che non sono mai stati inviati da nessuno)

mysql> select name from gifts LEFT OUTER JOIN sentgifts 
      ON gifts.giftID = sentgifts.giftID 
      WHERE sentgifts.giftID IS NULL; 

In questo caso, viene prima utilizza on, e poi where. Il on esegue prima la corrispondenza, quindi where esegue il filtro "secondario"? O c'è una regola più generale dell'uso di on rispetto a where? Grazie.

+0

Molto simile a http://stackoverflow.com/questions/2559194/differenza-tra-e-del-uno-uno-uno –

+1

Questa domanda ha il titolo migliore dei due. – ripper234

risposta

38

WHERE è una parte dell'intera query SELECT, ON è una parte di ogni singolo join.

ON può riferirsi solo ai campi delle tabelle utilizzate in precedenza.

Quando non c'è una corrispondenza effettiva con un record nella tabella sinistra, LEFT JOIN restituisce un record dalla tabella di destra con tutti i campi impostati su NULLS. La clausola WHERE quindi valuta e filtra questo.

Nella tua query, vengono restituiti solo i record da gifts senza corrispondenza in "sentgifts".

Ecco l'esempio

gifts 

1 Teddy bear 
2 Flowers 

sentgifts 

1 Alice 
1 Bob 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 

--- 

1 Teddy bear 1  Alice 
1 Teddy bear 1  Bob 
2 Flowers  NULL NULL -- no match in sentgifts 

--- 
SELECT * 
FROM gifts g 
LEFT JOIN 
     sentgifts sg 
ON  g.giftID = sg.giftID 
WHERE sg.giftID IS NULL 

--- 

2 Flowers  NULL NULL -- no match in sentgifts 

Come si può vedere, non può competere con vera e propria può lasciare un NULL in sentgifts.id, in modo che solo i doni che non erano mai stati inviati vengono restituiti.

0

Se si utilizza un JOIN, è necessario specificare le condizioni alle quali si sta partecipando. Quella lista va in una clausola ON. Una clausola WHERE viene utilizzata per condizionare i dati per qualsiasi punto della query.

2

Sebbene i risultati siano gli stessi, "ON" effettua prima il join e quindi recupera i dati del set unito. Il recupero è più veloce e il carico è inferiore. Ma usando 'WHERE' è necessario prima recuperare i due set di risultati e quindi applicare la condizione. Quindi sai cosa è preferibile.

11

Quando si utilizza INNER JOIN, ON e WHERE avrà lo stesso risultato. Così,

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
where t1.Name = 'John' 

avranno la stessa uscita esattamente come

select * 
from Table1 t1 
inner join Table2 t2 on t1.id = t2.id 
    and t1.Name = 'John' 

Come avrete notato, questo non è il caso quando si utilizza OUTER JOIN. Il piano di query che viene creato dipende dalla piattaforma del database e dalle specifiche della query ed è soggetto a modifiche, quindi prendere decisioni su tale base da solo non darà un piano di query garantito.

Come regola generale, è necessario utilizzare le colonne che uniscono le tabelle nelle clausole ON e nelle colonne utilizzate per il filtro nelle clausole WHERE. Questo fornisce la migliore leggibilità.

+0

È giusto usare "ON" con qualcosa di più complesso di field1 = field2? – skan

+0

Sì, ci sono spesso clausole ON a più colonne. – RedFilter

+0

Intendevo, puoi usare espressioni complesse oltre il confronto tra colonne? – skan

40

La clausola ON definisce la relazione tra le tabelle.

La clausola WHERE descrive quali righe che si interessa.

Molte volte li possibile scambiare e ancora ottenere lo stesso risultato, tuttavia questo non è sempre il caso con un join esterno sinistro.

  • Se la clausola ON non è ancora ottenere una riga con colonne della tabella a sinistra, ma con valori nulli nelle colonne della tabella di destra.
  • Se la clausola WHERE non funziona, non si otterrà alcuna riga.
+0

Valore in eccesso per le ultime due dichiarazioni – Sekai

Problemi correlati