Domanda

Ho la seguente query:

SELECT c.*
FROM companies AS c
JOIN users AS u USING(companyid)
JOIN jobs AS j USING(userid)
JOIN useraccounts AS us USING(userid)
WHERE j.jobid = 123;

Ho le seguenti domande:

  1. La sintassi USING è sinonimo di sintassi ON?
  2. Questi join vengono valutati da sinistra a destra? In altre parole, questa query dice: x = aziende JOIN utenti; y = x lavori JOIN; z = y JOIN accountaccount;
  3. Se la risposta alla domanda 2 è affermativa, è sicuro supporre che la tabella delle aziende abbia colonne companyid, userid e jobid?
  4. Non capisco come la clausola WHERE possa essere utilizzata per selezionare le righe nella tabella delle società quando si riferisce all'alias "j".

Qualsiasi aiuto sarebbe apprezzato!

È stato utile?

Soluzione

  1. USARE (fieldname) è un modo abbreviato di dire ON table1.fieldname = table2.fieldname.

  2. SQL non definisce l'ordine in cui vengono eseguiti i JOIN perché non è la natura della lingua. Ovviamente un ordine deve essere specificato nella dichiarazione, ma un INNER JOIN può essere considerato commutativo: puoi elencarli in qualsiasi ordine e otterrai gli stessi risultati.

    Detto questo, durante la costruzione di un SELECT ... JOIN, in particolare uno che include LEIN JOIN, ho trovato sensato considerare il terzo JOIN come unire la nuova tabella ai risultati del primo JOIN, il quarto JOIN come unendo i risultati del secondo JOIN, e così via.

    Più raramente, l'ordine specificato può influenzare il comportamento di Query Optimizer, a causa del modo in cui influenza l'euristica.

  3. No. Il modo in cui viene assemblata la query richiede che sia le aziende che gli utenti dispongano di un ID azienda, i lavori abbiano un ID utente e un ID lavoro e gli account utente abbiano un ID utente. Tuttavia, solo una delle società o ha bisogno di un ID utente per far funzionare il JOIN.

  4. La clausola WHERE sta filtrando l'intero risultato, ovvero tutte le colonne JOINed, utilizzando una colonna fornita dalla tabella dei lavori.

Altri suggerimenti

Non posso rispondere un po 'della sintassi USING. Quello è strano. Non l'ho mai visto prima, avendo sempre usato una clausola ON.

Ma ciò che posso sapere è che l'ordine delle operazioni JOIN è determinato dinamicamente da Query Optimizer quando costruisce il suo piano di query, basato su un sistema di euristica di ottimizzazione, alcuni dei quali sono:

  1. Il JOIN viene eseguito su un campo chiave primaria? In tal caso, questo ha la massima priorità nel piano di query.

  2. Il JOIN viene eseguito su un campo chiave esterna? Anche questo ha la massima priorità.

  3. Esiste un indice nel campo unito? In tal caso, aumentare la priorità.

  4. È stata eseguita un'operazione JOIN su un campo nella clausola WHERE? L'espressione della clausola WHERE può essere valutata esaminando l'indice (anziché eseguendo una scansione della tabella)? Questa è un'opportunità di ottimizzazione importante , quindi ha un grosso impatto prioritario.

  5. Qual è la cardinalità della colonna unita? Le colonne con cardinalità elevata offrono all'ottimizzatore maggiori opportunità di discriminare le false corrispondenze (quelle che non soddisfano la clausola WHERE o la clausola ON), quindi i join con cardinalità elevata vengono generalmente elaborati prima dei join con cardinalità bassa.

  6. Quante righe effettive ci sono nella tabella unita? Partecipare a una tabella con solo 100 valori creerà meno un'esplosione di dati rispetto a una tabella con dieci milioni di righe.

Comunque ... il punto è ... ci sono MOLTE variabili che vanno nel piano di esecuzione della query. Se vuoi vedere come MySQL ottimizza le sue query, usa la sintassi EXPLAIN.

Ed ecco un buon articolo da leggere:

http://www.informit.com/articles/article.aspx? p = 377652


ON EDIT:

Per rispondere alla tua quarta domanda: non stai interrogando le " società " tavolo. Stai interrogando il prodotto incrociato unito di TUTTI quattro tabelle nelle clausole FROM e USING.

Il " j.jobid " alias è solo il nome completo di una delle colonne in quella raccolta di tabelle unita.

In MySQL, è spesso interessante chiedere a Query Optimizer cosa intende fare, con:

EXPLAIN SELECT [...]

Vedi " 7.2.1 Ottimizzazione delle query con EXPLAIN "

VEDI http://dev.mysql.com/doc/ refman / 5.0 / it / join.html

E inizia a leggere qui:


Partecipa all'elaborazione delle modifiche in MySQL 5.0.12

A partire da MySQL 5.0.12, i join naturali e i join con USING, comprese le varianti di join esterne, vengono elaborati secondo lo standard SQL: 2003. L'obiettivo era allineare la sintassi e la semantica di MySQL rispetto a NATURAL JOIN e JOIN ... USANDO secondo SQL: 2003. Tuttavia, queste modifiche nell'elaborazione dei join possono comportare colonne di output diverse per alcuni join. Inoltre, alcune query che sembrano funzionare correttamente nelle versioni precedenti devono essere riscritte per essere conformi allo standard.

Queste modifiche hanno cinque aspetti principali:

  • Il modo in cui MySQL determina le colonne dei risultati delle operazioni di join NATURAL o USING (e quindi il risultato dell'intera clausola FROM).

  • Espansione di SELECT * e SELECT tbl_name. * in un elenco di colonne selezionate.

  • Risoluzione dei nomi delle colonne nei join NATURAL o USING.

  • La trasformazione dei join NATURAL o USING in JOIN ... ON.

  • Risoluzione dei nomi di colonna nella condizione ON di un JOIN ... ON.

Non sono sicuro della parte ON vs USING (anche se questo website dice che sono uguali)

Per quanto riguarda la domanda di ordinazione, la sua specifica implementazione (e probabilmente la query). Molto probabilmente MYSQL prende un ordine durante la compilazione della richiesta. Se si desidera applicare un ordine particolare, è necessario "annidare" le query:

SELECT c.*
FROM companies AS c 
    JOIN (SELECT * FROM users AS u 
        JOIN (SELECT * FROM  jobs AS j USING(userid) 
              JOIN useraccounts AS us USING(userid) 
              WHERE j.jobid = 123)
    )

come per la parte 4: la clausola where limita le righe della tabella dei lavori a cui è possibile aderire. Quindi, se ci sono righe che si unirebbero a causa degli userid corrispondenti ma non hanno il jobid corretto, verranno omesse.

1) L'uso non è esattamente lo stesso di on, ma è una scorciatoia in cui entrambe le tabelle hanno una colonna con lo stesso nome su cui ti stai unendo ... vedi: http://www.java2s.com/Tutorial/MySQL/0100__Table-Join/ThekeywordUSINGcanbeetaht >

Secondo me è più difficile da leggere, quindi vorrei andare a precisare i join.

3) Non è chiaro da questa domanda, ma immagino che non lo sia.

2) Supponendo che si stia unendo tramite le altre tabelle (non tutte direttamente nelle società) l'ordine in questa query è importante ... vedere i confronti di seguito:

originale di:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u USING(companyid) 
    JOIN jobs AS j USING(userid) 
    JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

Quello che penso stia probabilmente suggerendo:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u on u.companyid = c.companyid
    JOIN jobs AS j on j.userid = u.userid
    JOIN useraccounts AS us on us.userid = u.userid 
WHERE j.jobid = 123

Potresti cambiare le tue linee unendo i lavori & amp; account utenti qui.

Come sarebbe se tutto entrasse a far parte dell'azienda:

SELECT c.* 
    FROM companies AS c 
    JOIN users AS u on u.companyid = c.companyid
    JOIN jobs AS j on j.userid = c.userid
    JOIN useraccounts AS us on us.userid = c.userid
WHERE j.jobid = 123

Questo non ha davvero senso logico ... a meno che ogni utente non abbia la propria compagnia.

4.) La magia di sql è che puoi mostrare solo determinate colonne ma tutte sono loro per l'ordinamento e il filtro ...

se sei tornato

SELECT c.*, j.jobid....  

puoi vedere chiaramente su cosa stava filtrando, ma al server di database non importa se hai emesso una riga o meno per il filtro.

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