Jaki jest powód używania podwójnego łączenia wewnętrznego w tej instrukcji SQL?

10

Patrzę na to starsze zapytanie SQL. Nie jestem w stanie zrozumieć, dlaczego łączy wewnętrznie ten sam stół dwa razy w tych samych kolumnach. Mówię o tabelach Table1 i Table1 połączonych z aliasem „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'
Matematyka
źródło

Odpowiedzi:

27

Może to pomóc w przepisaniu zapytania w ten sposób, więc oczywiste jest, że 2 sprzężenia są różne , tzn. Sprzężenia dotyczą różnych podzbiorów (tej samej tabeli):

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' 
ypercubeᵀᴹ
źródło
nie jest GDZIE należy zastosować PO sprzężeniach, tzn. zgodziłbym się, czy ograniczenia te były częścią instrukcji złączenia, tj. połączone przez AND, ale GDZIE we wszystkich doświadczeniach stosuje się do wyniku sprzężenia odfiltrowującego wiersze z połączony stół, nie wpływając na faktyczne połączenie.
Frank Hopkins
3
@Darkwing O ile mi wiadomo, nie ma znaczenia, gdzie stawiasz warunki, ponieważ zadaniem optymalizatora zapytań jest opracowanie najlepszego planu egzekucji. Lepiej jednak umieścić je obok złącz, ponieważ dzięki temu są bardziej czytelne, ale to tylko opinia
Matematyka
Nawet gdyby miało to nastąpić PO dołączeniu wyniki łączenia są na końcu inne. I tak, połączone wiersze są zwykle filtrowane przed łączeniem, ponieważ poprawia to wydajność.
Gherman
1
Jest to również równoważne z łączeniem z podzapytaniem, np INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. To może sprawić, że stanie się jeszcze bardziej oczywiste.
Barmar
3
@ Matematyka - to, czy warunek jest w ONklauzuli złączenia, czy w WHEREklauzuli, może mieć duże znaczenie, jeśli łączenie jest an OUTER JOIN. Jeśli warunek nie powiedzie się w ONklauzuli, pierwszy wiersz jest nadal uwzględniany (bez pasującego zewnętrznego wiersza); jeśli zawiedzie w WHEREklauzuli, wówczas wiersz główny jest wykluczony z zestawu wyników.
RDFozz
8

Patrząc na whereklauzulę, wiersz wskazywany przez table1wymaga kolumny type= = „0”, a wiersz wskazywany przez table1aliaswymaga kolumny columna= = „conn”.

Być może jest wiele wierszy table1dla tego samego id3?

Scott Hodgin
źródło
2

Nie widząc struktury tabeli - podejście może polegać na użyciu mniejszego indeksu niekryjącego, a następnie dołączeniu do tabeli na większym indeksie obejmującym, aby uzyskać resztę wierszy, aby uniknąć operacji „Key Lookup” i uniknąć modyfikacji istniejących indeksów (lub jeśli nie możesz modyfikować indeksów)

Allan S. Hansen
źródło
2

Ilekroć tabela pojawia się więcej niż raz w złożonym złączeniu, zwykle dzieje się tak, ponieważ istnieje byt, który uczestniczy w więcej niż jednym związku. Wydaje się, że tak jest w tym przypadku, sądząc po odpowiedzi udzielonej przez @Ypercube.

Podmioty i relacje są ogólnie rozumiane przez semantykę danych oraz połączenie z podstawową tematyką. Jeśli Twój starszy system został starannie zbudowany, prawdopodobnie starali się przeanalizować temat i dokładnie zdefiniować każdy z elementów danych. Mogli nawet zbudować model relacji jednostka-związek. Cała ta staranna praca mogła zostać utracona, a ty utknąłeś w jej rekonstrukcji poprzez kopanie w przeszłość. To trochę jak archeologia.

W przypadku nazw tabel takich jak Tabela 1 nie mamy pojęcia, jak działa Twój przedmiot. I nawet jeśli nazwy mają charakter opisowy, nasze rozumienie przedmiotu twojego systemu może się bardzo różnić od tego, co jest potrzebne w twoim przypadku. To zależy od ciebie.

Walter Mitty
źródło