JOIN

JOIN je syntaktická konstrukce jazyka SQL. Slouží ke spojování výsledku dotazu SELECT ze dvou vstupních množin (typicky tabulek relační databáze).

Použití

SELECT seznam_sloupců FROM tabulka1
[CROSS|INNER|NATURAL|LEFT|RIGHT|[FULL ]OUTER] JOIN tabulka2 ON podmínka
[WHERE podmínka] [ORDER BY sloupce] [LIMIT počet_záznamů];

Jako podmínka se typicky uvádí, které sloupce z obou tabulek se v tomto dotazu mají shodovat. Například příkaz:

SELECT produkty.id, produkty.nazev, dodavatele.nazev FROM produkty
LEFT JOIN dodavatele ON produkty.dodavatel_id = dodavatele.id
WHERE cena > 10000 ORDER BY cena DESC;

…vypíše (dejme tomu v databázi s produkty, na které je napojena tabulka dodavatelů) produkty s jejich id, názvem a názvem dodavatele. Všimněte si, že zatímco sloupec cena není uveden s prefixem tabulky, sloupce id a nazev jsou (a musejí být). Pokud by nebyly, databázový engine by nedokázat rozlišit, id nebo nazev které tabulky chceme vypsat, a nejspíš by vypsal chybovou hlášku „Column 'id' in field list is ambiguous“ nebo obdobnou.

Varianty spojování tabulek

Spojování tabulek může být:

  • křížové (CROSS JOIN)
  • vnitřní (INNER JOIN)
  • přirozené (NATURAL JOIN)
  • vnější (OUTER JOIN)
    • úplné vnější (FULL OUTER JOIN)
    • částečné vnější
      • „zleva“ (LEFT JOIN)
      • „zprava“ (RIGHT JOIN)

JOIN dle standardu SQL89

Podle standard SQL89 se spojované množiny zapisují v příkazu SELECT jako čárkami oddělený seznam klauzule FROM. Podmínky určující spojení množin se zapisují mezi filtrační podmínky v části WHERE. Takto lze specifikovat pouze spojování křížové a vnitřní.

JOIN dle standardu SQL92

Podle standardu SQL92 je spojovací podmínka nedílnou součástí klauzule FROM příkazu SELECT. Tento způsob zápisu zavádí kromě křížového a vnitřního spojování i přirozené a vnější.

Křížové spojování

Výsledkem křížového spojování (CROSS JOIN) je kartézský součin vstupních množin. Výsledná množina je většinou velmi rozsáhlá. Ekvivalentem křížového spojování je vnitřní spojování s podmínkou, která je platná pro všechny řádky vstupních množin.

Příklad

Výstupní množina pro uvedené zápisy je shodná.

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a, tab2 b;

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a CROSS JOIN tab2 b;

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a INNER JOIN tab2 b ON 1 = 1

Vnitřní spojování

Vnitřní spojování (INNER JOIN) je v praxi nejčastěji používaným způsobem spojování vstupních množin. Je to křížové spojování omezené na výstupu o řádky nevyhovující spojovací podmínce. Typicky je podmínka definovaná jako rovnost primárního klíče a cizího klíče.

Příklad

Výstupní množina pro uvedené zápisy je shodná.

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a, tab2 b WHERE a.col1 = b.col1;

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a INNER JOIN tab2 b ON a.col1 = b.col1;

Spojení přes více polí

SELECT a.col1, a.col2, a.col3, a.col4, b.col1, b.col2, b.col3, b.col4
FROM tab1 a INNER JOIN tab2 b ON (a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 = b.col3);

Přirozené spojování

Přirozené spojování (NATURAL JOIN) je zvláštním případem vnitřního spojování, kde je spojovací podmínka realizována automaticky dle přítomnosti referenčních vazeb nebo shodnosti názvů sloupců a datových typů ve spojovaných tabulkách. Pro možnou nejednoznačnost není tento typ často používán, ani v databázových strojích nebývá implementován.

Příklad
SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a NATURAL JOIN tab2 b

Vnější spojování

Vnější spojování (OUTER JOIN) generuje výstupní množinu omezenou o spojovací podmínky podobně jako vnitřní spojování, pokud však není nalezen vhodný řádek v druhé množině, je nenalezený řádek nahrazen hodnotami NULL. Dle typu vnějšího spojení mohou být doplňovány řádky z jedné nebo obou vstupních množin. Výsledkem vnějšího spojování jsou řádky naplněné hodnotami ze vstupních množin i částečně.

Úplné vnější spojování

Úplné vnější spojování (FULL OUTER JOIN) doplňuje NULL hodnoty do obou vstupních množin.

Příklad
SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a FULL OUTER JOIN tab2 b on a.col1 = b.col1

Částečné vnější spojování

Pro částečné vnější spojování jsou definována klíčová slova LEFT a RIGHT, která definují, která vstupní množina má zahrnuté všechny řádky v množině výstupní, tj. která vstupní množina není doplňována o NULL hodnoty.

Příklad
SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a LEFT OUTER JOIN tab2 b ON a.col1 = b.col1

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a RIGHT OUTER JOIN tab2 b ON a.col1 = b.col1

V dialektu jazyka SQL, který používá systém Oracle byla do verze 8 syntaxe těchto spojení trochu jiná (od verze 9 lze užívat i výše uvedených standardních konstrukcí):

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a, tab2 b where a.col1 = b.col1 (+)

SELECT a.col1, a.col2, b.col1, b.col2
FROM tab1 a, tab2 b where a.col1 (+) = b.col1

Další vlastnosti

Spojování více než dvou tabulek

SQL umožňuje spojení pomocí JOIN pro teoreticky libovolné množství tabulek. Syntaxe je následující:

SELECT sloupce FROM ((((tabulka1 [INNER|LEFT|OUTER|...] JOIN tabulka2 ON sloupectabulky1=sloupectabulky2)
[INNER|LEFT|OUTER|...] JOIN tabulka3 ON sloupectabulky1nebo2 = sloupectabulky3)
[INNER|LEFT|OUTER|...] JOIN tabulka4 ON sloupectabulky1nebo2nebo3 = sloupectabulky4)
[INNER|LEFT|OUTER|...] JOIN tabulka5 ON sloupectabulky1nebo2nebo3nebo4 = sloupectabulky5)
...;

Pro některé databázové systémy nejsou závorky ve výše uvedeném příkladu povinné.

JOIN a NULL

NULL má v prostředí databází speciální místo. Někdy bývá považován za synonymum prázdné nebo „nulové hodnoty“, to je však častá chyba, protože ve skutečnosti bychom o NULL měli přemýšlet jako o „neurčité hodnotě“, s tím, že platí: NULL ≠ NULL (neurčitá hodnota ≠ neurčitá hodnota).

SELECT sloupce FROM tabulka1 LEFT JOIN tabulka2 ON tabulka1.sloupec=tabulka2.sloupec;

SELECT sloupce FROM tabulka1 INNER JOIN tabulka2 ON tabulka1.sloupec=tabulka2.sloupec;

Pro výše uvedený příklad se řádky, kde tabulka2.sloupec je NULL

  • pro spojení LEFT JOIN zobrazí.
  • pro spojení INNER JOIN nezobrazí.

Řádky, kde tabulka1.sloupec je NULL, se nezobrazí v žádném z případů. Dokonce ani při FULL OUTER JOINu: Podobně jako v dílčích tabulkách nejsou obsaženy řádky složené pouze z hodnot NULL (za předpokladu zavedeného primárního klíče), ani jejich FULL JOINem žádné takové NULLxNULL nevzniknou. Aby se řádek najoinoval, musel by nejdříve existovat, aby s ním pak mohlo být takto manipulováno.

Odkazy

Související články

Externí odkazy