Qual è la ragione per usare il doppio join interno in questa istruzione SQL?


10

Sto guardando questa query SQL legacy. Il bit che non riesco a ottenere è il motivo per cui è interno unire due volte la stessa tabella sulle stesse colonne. Sto parlando di Table1 e Table1 uniti con l'alias "Table1Alias",

SELECT DISTINCT othercolumns,
                Table1Alias.columna
FROM   maintable
       INNER JOIN secondarytable
               ON maintable.id1 = secondarytable.a_id1
       INNER JOIN table1
               ON secondarytable.id2 = table1.id3
       INNER JOIN table1 Table1Alias
               ON secondarytable.id2 = Table1Alias.id3
       INNER JOIN thirdtable
               ON table1.id4 = thirdtable.id5
       INNER JOIN fourthtable
               ON thirdtable.id6 = fourthtable.id7
       INNER JOIN fivetable
               ON thirdtable.id8 = fivetable.id9
       INNER JOIN sixthtable
               ON Table1Alias.columna = sixthtable.id10
       LEFT JOIN seventhtable
              ON thirdtable.id11 = seventhtable.id12
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09'
       AND secondarytable.type456 = 'cate'
       AND table1.type = '0'
       AND Table1Alias.columna = 'conn'

Risposte:


27

Potrebbe essere utile riscrivere la query in questo modo, quindi è ovvio che i 2 join sono diversi , vale a dire che i join appartengono a sottoinsiemi diversi (della stessa tabella):

FROM   maintable 
       INNER JOIN secondarytable 
               ON maintable.id1 = secondarytable.a_id1 
       INNER JOIN table1 
               ON secondarytable.id2 = table1.id3 
              AND table1.type = '0' 
       INNER JOIN table1 Table1Alias 
               ON secondarytable.id2 = Table1Alias.id3 
              AND Table1Alias.columna = 'conn' 
       INNER JOIN
       ...
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09' 
       AND secondarytable.type456 = 'cate' 

non è il DOVE da applicare DOPO i join, cioè concordo sul fatto che quei vincoli facessero parte dell'istruzione join, ovvero collegati da un AND, ma il WHERE in tutta l'esperienza viene applicato al risultato del join che filtra le righe da la tabella unita, senza influenzare la join effettiva.
Frank Hopkins,

3
@Darkwing Per quanto ne so, non importa dove metti le condizioni, in quanto è compito di Query Optimizer elaborare il miglior piano di esecuzione. Tuttavia è meglio metterli vicino ai join in quanto li rende più leggibili ma è solo un'opinione
Matematica

Anche se dovesse succedere DOPO l'unione i risultati dei join sono diversi alla fine. E sì, le righe unite vengono generalmente filtrate prima di unirsi poiché migliora le prestazioni.
Gherman,

1
È anche equivalente all'unione con una sottoquery, ad es INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. Ciò potrebbe rendere ancora più ovvio ciò che sta accadendo.
Barmar,

3
@Matematica: se una condizione è nella ONclausola di un join o nella WHEREclausola può essere molto importante se il join è un OUTER JOIN. Se una condizione non riesce nella ONclausola, la riga principale viene comunque inclusa (senza una riga esterna corrispondente); se non riesce nella WHEREclausola, la riga principale viene esclusa dal set di risultati.
RDFozz,

8

Guardando la whereclausola, la riga a cui punta punta table1la colonna typesu = '0' e la riga a cui punta punta table1aliasla colonna columnasu = 'conn'.

Forse ci sono più file table1per lo stesso id3?


2

Senza vedere la struttura della tabella - l'approccio potrebbe essere quello di utilizzare un indice non di copertura più piccolo e quindi unirsi alla tabella su un indice di copertura più grande per ottenere il resto delle righe per evitare un'operazione di "Ricerca chiave" ed evitare di modificare gli indici esistenti (o se non è possibile modificare gli indici)


2

Ogni volta che una tabella appare più di una volta in un join complesso, di solito è perché esiste un'entità che partecipa a più di una relazione. Questo sembra essere il caso qui, a giudicare dalla risposta che @Ypercube ha dato.

Le entità e le relazioni sono generalmente comprese attraverso la semantica dei dati e la connessione con l'oggetto sottostante. Se il tuo sistema legacy è stato creato con cura, probabilmente si sono presi cura di analizzare l'argomento e definire con attenzione ciascuno degli elementi di dati. Potrebbero persino aver costruito un modello Entità-Relazione. Tutto quel lavoro attento potrebbe essere andato perso e tu sei bloccato a ricostruirlo scavando nel passato. Questo è un po 'come l'archeologia.

Con nomi di tabelle come Table1, non abbiamo la minima idea di come funzioni il tuo argomento. E anche se i nomi fossero descrittivi, la nostra comprensione dell'oggetto del tuo sistema potrebbe essere molto diversa da quella necessaria nel tuo caso. Sta a te.

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.