Domanda

Per semplicità, supponiamo che tutti i campi rilevanti lo siano NOT NULL.

Tu puoi fare:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1, table2
WHERE
    table1.foreignkey = table2.primarykey
    AND (some other conditions)

O altro:

SELECT
    table1.this, table2.that, table2.somethingelse
FROM
    table1 INNER JOIN table2
    ON table1.foreignkey = table2.primarykey
WHERE
    (some other conditions)

Questi due funzionano allo stesso modo MySQL?

È stato utile?

Soluzione

INNER JOIN è la sintassi ANSI che dovresti usare.

È generalmente considerato più leggibile, specialmente quando si uniscono molti tavoli.

Può anche essere facilmente sostituito con un OUTER JOIN ogni volta che si presenta una necessità.

La sintassi WHERE è più orientata al modello relazionale.

Un risultato di due tabelle JOIN ed è un prodotto cartesiano delle tabelle a cui viene applicato un filtro che seleziona solo quelle righe con corrispondenza delle colonne unite.

È più facile vederlo con la STRAIGHT_JOIN sintassi.

Come nel tuo esempio, in MySQL (e in SQL in generale) queste due query sono sinonimi.

Nota anche che MySQL ha anche una <=> clausola.

Usando questa clausola, puoi controllare l'ordine <=>: quale tabella viene scansionata nel ciclo esterno e quale si trova nel ciclo interno.

Non puoi controllarlo in MySQL usando la sintassi <=>.

Altri suggerimenti

Altri hanno sottolineato che INNER JOIN aiuta la leggibilità umana, e questa è una priorità assoluta; Sono d'accordo. Vorrei provare a spiegare perché la sintassi del join è più leggibile.

Una query SELECT di base è questa:

SELECT stuff
FROM tables
WHERE conditions

La clausola SELECT ci dice cosa stiamo tornando; la clausola FROM ci dice da dove la stiamo ottenendo e la clausola WHERE ci dice quali stiamo ottenendo.

JOIN è una dichiarazione sulle tabelle, su come sono legate insieme (concettualmente, in realtà, in una singola tabella). Tutti gli elementi di query che controllano le tabelle - da cui stiamo ottenendo elementi - appartengono semanticamente alla clausola FROM (e, naturalmente, è qui che vanno gli elementi JOIN). Inserendo elementi di giunzione nella clausola WHERE si fondono il che e il da dove ; ecco perché è preferita la sintassi JOIN.

Applicazione delle istruzioni condizionali in ON / WHERE

Qui ho spiegato le fasi di elaborazione delle query logiche.


Riferimento: Inside Microsoft & # 174; SQL Server & # 8482; 2005 T-SQL Querying
Editore: Microsoft Press
Data pub: 07 marzo 2006
Stampa ISBN-10: 0-7356-2313-9
Stampa ISBN-13: 978-0-7356-2313-2
Pagine: 640

Inside Microsoft # 174; SQL Server & # 8482; 2005 T-SQL Querying

(8)  SELECT (9) DISTINCT (11) TOP <top_specification> <select_list>
(1)  FROM <left_table>
(3)       <join_type> JOIN <right_table>
(2)       ON <join_condition>
(4)  WHERE <where_condition>
(5)  GROUP BY <group_by_list>
(6)  WITH {CUBE | ROLLUP}
(7)  HAVING <having_condition>
(10) ORDER BY <order_by_list>

Il primo aspetto evidente di SQL diverso dagli altri linguaggi di programmazione è l'ordine in cui il codice viene elaborato. Nella maggior parte dei linguaggi di programmazione, il codice viene elaborato nell'ordine in cui è scritto. In SQL, la prima clausola che viene elaborata è la clausola FROM, mentre la clausola SELECT, che appare per prima, viene elaborata quasi per ultima.

Ogni passaggio genera una tabella virtuale che viene utilizzata come input per il passaggio successivo. Queste tabelle virtuali non sono disponibili per il chiamante (applicazione client o query esterna). Solo la tabella generata dal passaggio finale viene restituita al chiamante. Se una determinata clausola non viene specificata in una query, il passaggio corrispondente viene semplicemente ignorato.

Breve descrizione delle fasi di elaborazione delle query logiche

Non preoccuparti troppo se la descrizione dei passaggi non sembra avere molto senso per ora. Questi sono forniti come riferimento. Le sezioni che seguono l'esempio dello scenario copriranno i passaggi in modo molto più dettagliato.

  1. FROM: un prodotto cartesiano (cross join) viene eseguito tra le prime due tabelle nella clausola FROM e, di conseguenza, viene generata la tabella virtuale VT1.

  2. ON: il filtro ON viene applicato a VT1. Solo le righe per le quali <join_condition> è TRUE sono inserite in VT2.

  3. OUTER (join): se viene specificato un OUTER JOIN (al contrario di un CROSS JOIN o un INNER JOIN), le righe della tabella conservata o le tabelle per le quali non è stata trovata una corrispondenza vengono aggiunte alle righe da VT2 come file esterne, generando VT3. Se vengono visualizzate più di due tabelle nella clausola FROM, i passaggi da 1 a 3 vengono applicati ripetutamente tra il risultato dell'ultimo join e la tabella successiva nella clausola FROM fino a quando non vengono elaborate tutte le tabelle.

  4. DOVE: il filtro WHERE viene applicato a VT3. Solo le righe per le quali <where_condition> è TRUE sono inserite in VT4.

  5. GROUP BY: le righe da VT4 sono organizzate in gruppi in base all'elenco di colonne specificato nella clausola GROUP BY. Viene generato VT5.

  6. CUBE | ROLLUP: i supergruppi (gruppi di gruppi) vengono aggiunti alle righe da VT5, generando VT6.

  7. HAVING: il filtro HAVING viene applicato a VT6. Solo i gruppi per i quali <having_condition> è TRUE sono inseriti in VT7.

  8. SELECT: l'elenco SELECT viene elaborato, generando VT8.

  9. DISTINCT: le righe duplicate vengono rimosse da VT8. Viene generato VT9.

  10. ORDER BY: le righe da VT9 sono ordinate in base all'elenco di colonne specificato nella clausola ORDER BY. Viene generato un cursore (VC10).

  11. INIZIO: il numero o la percentuale di righe specificato viene selezionato dall'inizio di VC10. La tabella VT11 viene generata e restituita al chiamante.



     Pertanto, (INNER JOIN) ON filtrerà i dati (il conteggio dei dati di VT verrà ridotto qui stesso) prima di applicare la clausola WHERE. Le condizioni di join successive verranno eseguite con dati filtrati che migliorano le prestazioni. Successivamente solo la condizione WHERE applicherà le condizioni del filtro.

(L'applicazione delle istruzioni condizionali in ON / WHERE non farà molta differenza in alcuni casi. Dipende da quante tabelle sono state unite e dal numero di righe disponibili in ciascuna tabella di join)

La sintassi ANSI di join implicita è più vecchia, meno ovvia e sconsigliata.

Inoltre, l'algebra relazionale consente l'interscambiabilità dei predicati nella clausola WHERE e nella INNER JOIN, quindi anche <=> query con clausole <=> possono fare in modo che i predicati vengano riorganizzati dall'ottimizzatore.

Ti consiglio di scrivere le query nel modo più leggibile possibile.

A volte questo include rendere <=> relativamente " incomplete " e inserendo alcuni dei criteri in <=> semplicemente per rendere più facilmente gestibili gli elenchi dei criteri di filtro.

Ad esempio, anziché:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
    AND c.State = 'NY'
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
    AND a.Status = 1

Scrivi:

SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
    ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
    ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
    AND a.Status = 1

Ma dipende, ovviamente.

I join impliciti (che è la cosiddetta prima query) diventano molto più confusi, difficili da leggere e difficili da mantenere una volta che è necessario iniziare ad aggiungere più tabelle alla query. Immagina di fare la stessa query e lo stesso tipo di join su quattro o cinque diversi tavoli ... è un incubo.

L'uso di un join esplicito (il tuo secondo esempio) è molto più leggibile e facile da mantenere.

Sottolineerò anche che l'utilizzo della sintassi precedente è più soggetto a errori.Se utilizzi inner join senza una clausola ON, riceverai un errore di sintassi.Se utilizzi la sintassi precedente e dimentichi una delle condizioni di join nella clausola where, otterrai un cross join.Gli sviluppatori spesso risolvono questo problema aggiungendo la parola chiave distinti (invece di correggere il join perché ancora non si rendono conto che il join stesso è interrotto) che potrebbe sembrare risolvere il problema, ma rallenterà notevolmente la query.

Inoltre, per la manutenzione, se hai un cross join nella vecchia sintassi, come farà il manutentore a sapere se intendevi averne uno (ci sono situazioni in cui sono necessari i cross join) o se si è trattato di un incidente che dovrebbe essere risolto?

Lascia che ti indichi questa domanda per capire perché la sintassi implicita è errata se usi i left join.Sybase *= secondo lo standard Ansi con 2 diverse tabelle esterne per la stessa tabella interna

Inoltre (sfogo personale qui), lo standard che utilizza i join espliciti ha più di 20 anni, il che significa che la sintassi dei join impliciti è obsoleta per quei 20 anni.Scriveresti il ​​codice dell'applicazione utilizzando una sintassi obsoleta da 20 anni?Perché vuoi scrivere il codice del database?

Hanno un diverso significato leggibile dall'uomo.

Tuttavia, a seconda di Query Optimizer, potrebbero avere lo stesso significato per la macchina.

Dovresti sempre codificare per essere leggibile.

Vale a dire, se si tratta di una relazione integrata, utilizzare il join esplicito. se si esegue la corrispondenza su dati debolmente correlati, utilizzare la clausola where.

Lo standard SQL: 2003 ha modificato alcune regole di precedenza in modo che un'istruzione JOIN abbia la precedenza su una " virgola " aderire. Ciò può effettivamente modificare i risultati della query in base alla configurazione. Ciò causa alcuni problemi per alcune persone quando MySQL 5.0.12 è passato all'adesione allo standard.

Quindi, nel tuo esempio, le tue query funzionerebbero allo stesso modo. Ma se hai aggiunto una terza tabella: SELEZIONA ... DA table1, table2 UNISCITI table3 SU ... DOVE ...

Prima di MySQL 5.0.12, table1 e table2 sarebbero stati uniti per primi, quindi table3. Ora (5.0.12 e successivi), table2 e table3 vengono unite prima, quindi table1. Non cambia sempre i risultati, ma può e potresti anche non rendertene conto.

Non uso mai il " virgola " sintassi più, optando per il tuo secondo esempio. È comunque molto più leggibile, le condizioni JOIN sono con i JOIN, non separate in una sezione di query separata.

So che stai parlando di MySQL, ma comunque: In Oracle 9 i join espliciti e i join impliciti genererebbero piani di esecuzione diversi. AFAIK che è stato risolto in Oracle 10+: non c'è più tale differenza.

La sintassi del join ANSI è decisamente più portatile.

Sto attraversando un aggiornamento di Microsoft SQL Server e vorrei anche menzionare che la sintassi = * e * = per i join esterni in SQL Server non è supportata (senza modalità di compatibilità) per 2005 sql server e versioni successive.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top