Nelle query MySQL, perché usare join invece di dove?


109

Sembra che si combinino due o più tabelle, possiamo usare join o where. Quali sono i vantaggi dell'uno rispetto all'altro?


2
A seconda del tuo utilizzo, potrebbe avere gli stessi risultati, ma con un JOIN puoi fare altri tipi di associazioni.
Zneak

Questo risponde alla tua domanda? Clausola INNER JOIN ON vs WHERE
philipxy

Risposte:


161

Qualsiasi query che coinvolge più di una tabella richiede una qualche forma di associazione per collegare i risultati dalla tabella "A" alla tabella "B". Il metodo tradizionale (ANSI-89) per farlo è:

  1. Elenca le tabelle coinvolte in un elenco separato da virgole nella clausola FROM
  2. Scrivi l'associazione tra le tabelle nella clausola WHERE

    SELECT *
      FROM TABLE_A a,
           TABLE_B b
     WHERE a.id = b.id

Ecco la query riscritta utilizzando la sintassi ANSI-92 JOIN:

SELECT *
  FROM TABLE_A a
  JOIN TABLE_B b ON b.id = a.id

Dal punto di vista delle prestazioni:


Dove supportato (Oracle 9i +, PostgreSQL 7.2+, MySQL 3.23+, SQL Server 2000+), non vi è alcun vantaggio in termini di prestazioni nell'utilizzo di una delle due sintassi rispetto all'altra. L'ottimizzatore li vede come la stessa query. Ma le query più complesse possono trarre vantaggio dall'utilizzo della sintassi ANSI-92:

  • Capacità di controllare l'ordine JOIN - l'ordine in cui le tabelle vengono scansionate
  • Possibilità di applicare criteri di filtro su una tabella prima di partecipare

Dal punto di vista della manutenzione:


Esistono numerosi motivi per utilizzare la sintassi ANSI-92 JOIN su ANSI-89:

  • Più leggibile, poiché il criterio JOIN è separato dalla clausola WHERE
  • Meno probabilità di perdere i criteri JOIN
  • Coerente supporto della sintassi per i tipi JOIN diversi da INNER, che semplifica l'utilizzo delle query su altri database
  • La clausola WHERE serve solo come filtraggio del prodotto cartesiano delle tavole unite

Da una prospettiva di progettazione:


La sintassi ANSI-92 JOIN è pattern, non anti-pattern:

  • Lo scopo della query è più ovvio; le colonne utilizzate dall'applicazione sono chiare
  • Segue la regola di modularità sull'uso della tipizzazione rigorosa quando possibile. Explicit è quasi universalmente migliore.

Conclusione


A parte la familiarità e / o il comfort, non vedo alcun vantaggio nel continuare a utilizzare la clausola ANSI-89 WHERE invece della sintassi ANSI-92 JOIN. Alcuni potrebbero lamentarsi del fatto che la sintassi ANSI-92 è più prolissa, ma questo è ciò che la rende esplicita. Più è esplicito, più è facile comprenderlo e mantenerlo.


14
"... Qualsiasi query che coinvolge più di una tabella richiede una qualche forma di associazione per collegare i risultati dalla tabella" A "alla tabella" B "... Altrimenti otterrai un prodotto cartesiano e probabilmente non lo vorrai (quei cartesiani fanno prodotti scadenti)
Scott Smith

8

La maggior parte delle persone tende a trovare la sintassi JOIN un po 'più chiara su cosa viene unito a cosa. Inoltre, ha il vantaggio di essere uno standard.

Personalmente sono "cresciuto" con WHERE, ma più uso la sintassi JOIN più comincio a vedere come sia più chiaro.


1
@nawfal Capisco - Sono cresciuto con la sintassi vecchio stile ma una volta che mi sono abituato a quella nuova, i vantaggi sono diventati chiari, ad esempio più difficile fare un cross join per errore, più esplicito, più facile vedere cos'è un join e cosa un filtro, ecc ... mi sono appassionato.
Basic

8

Questi sono i problemi con l'utilizzo della sintassi where (altrimenti noto come join implicito):

Innanzitutto, è fin troppo facile ottenere cross join accidentali perché le condizioni di join non sono proprio accanto ai nomi delle tabelle. Se hai 6 tabelle unite insieme, è facile perderne una nella clausola where. Vedrai che questo problema è stato risolto troppo spesso utilizzando la parola chiave distinta. Questo è un enorme calo di prestazioni per il database. Non è possibile ottenere un cross join accidentale utilizzando la sintassi esplicita del join poiché non supererà il controllo della sintassi.

I join destro e sinistro sono problematici (nel server SQl non è garantito di ottenere i risultati corretti) nella vecchia sintassi in alcuni database. Inoltre sono deprecati in SQL Server, lo so.

Se intendi utilizzare un cross join, ciò non è chiaro dalla vecchia sintassi. È chiaro usando l'attuale standard ANSII.

È molto più difficile per il manutentore vedere esattamente quali campi fanno parte del join o anche quali tabelle si uniscono in quale ordine utilizzando la sintassi implicita. Ciò significa che potrebbe essere necessario più tempo per rivedere le query. Ho conosciuto pochissime persone che, una volta che si sono presi il tempo per sentirsi a proprio agio con la sintassi esplicita di join, sono mai tornate alla vecchia maniera.

Ho anche notato che alcune persone che usano questi join impliciti non capiscono effettivamente come funzionano i join e quindi ottengono risultati errati nelle loro query.

Onestamente, useresti un altro tipo di codice che è stato sostituito con un metodo migliore 18 anni fa?


6

I join espliciti trasmettono l'intento, lasciando la clausola where a fare il filtro. È più pulito ed è standard, e puoi fare cose come esterno sinistro o esterno destro che è più difficile da fare solo con dove.


3

Non puoi usare WHERE per combinare due tabelle. Quello che puoi fare però è scrivere:

SELECT * FROM A, B
WHERE ...

La virgola qui equivale a scrivere:

SELECT *
FROM A
CROSS JOIN B
WHERE ...

Lo scriveresti? No, perché non è affatto quello che intendi. Non vuoi un cross join, vuoi un INNER JOIN. Ma quando scrivi la virgola, stai dicendo CROSS JOIN e questo crea confusione.


0

In realtà spesso hai bisogno sia di "WHERE" che di "JOIN".

"JOIN" viene utilizzato per recuperare i dati da due tabelle, in base ai valori di una colonna comune. Se poi vuoi filtrare ulteriormente questo risultato, usa la clausola WHERE.

Ad esempio, "LEFT JOIN" recupera TUTTE le righe dalla tabella di sinistra, più le righe corrispondenti dalla tabella di destra. Ma ciò non filtra i record su alcun valore specifico o su altre colonne che non fanno parte del JOIN. Pertanto, se si desidera filtrare ulteriormente questo risultato, specificare i filtri aggiuntivi nella clausola WHERE.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.