Vnitřní spojení vyžaduje, aby každý řádek ve dvou spojených tabulkách měl shodné hodnoty sloupců a je běžně používanou operací spojení v aplikacích, ale neměl by být považován za nejlepší volbu ve všech situacích. Vnitřní spojení vytvoří novou tabulku výsledků kombinací hodnot sloupců dvou tabulek (A a B) na základě predikátu spojení. Dotaz porovnává každý řádek A s každým řádkem B, aby našel všechny páry řádků, které splňují predikát spojení. Když je spojovací predikát uspokojen porovnáním hodnot, které nemají hodnotu NULL, hodnoty sloupců pro každou shodnou dvojici řádků A a B se spojí do řádku výsledku.
Výsledek spojení lze definovat jako výsledek prvního převzetí kartézského součinu (nebo křížového spojení) všech řádků v tabulkách (kombinace každého řádku v tabulce A s každým řádkem v tabulce B) a následného vrácení všech řádků, které splňují predikát spojení. Skutečné implementace SQL obvykle používají jiné přístupy, například hašovací spojení nebo řazení-sloučení spojení, protože výpočet kartézského produktu je pomalejší a pro jeho uložení by často bylo zapotřebí neúměrně velké množství paměti.
SQL specifikuje dva různé syntaktické způsoby, jak vyjádřit spojení: „explicitní zápis spojení“ a „implicitní zápis spojení“. „Implicitní spojovací notace“ již není považována za osvědčený postup, přestože ji databázové systémy stále podporují.
„Explicitní spojovací notace“ používá klíčové slovo JOIN
, volitelně předchází klíčové slovo INNER
k určení tabulky, ke které se chcete připojit, a klíčové slovo ON
k zadání predikátů pro připojení, jako v následující příklad:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee INNER JOIN department ONemployee.DepartmentID = department.DepartmentID;
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
administrativní |
Jones |
33 |
inženýrství |
Smith |
34 |
administrativní |
Heisenberg |
33 |
Inženýrství |
Rafferty |
31 |
Prodej |
„Implicitní zápis spojení“ jednoduše uvádí t Tabulky pro připojení v klauzuli FROM
příkazu SELECT
oddělením čárkami. Určuje tedy křížové spojení a klauzule WHERE
může použít další predikáty filtru (které fungují srovnatelně s predikáty spojení v explicitní notaci).
Následující příklad je ekvivalentní předchozímu, ale tentokrát s použitím implicitní spojovací notace:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Dotazy uvedené v příkladech výše se připojí k tabulkám Zaměstnanec a Oddělení pomocí sloupce Oddělení ID obou tabulek. Pokud se DepartmentID těchto tabulek shoduje (tj. Predikát spojení je splněn), bude dotaz kombinovat sloupce LastName, DepartmentID a DepartmentName ze dvou tabulek do řádku výsledků. Pokud se ID oddělení neshoduje, nevygeneruje se žádný řádek s výsledky.
Výsledek provedení výše uvedeného dotazu tedy bude:
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
administrativní |
Jones |
33 |
Inženýrství |
Smith |
34 |
Administrativní |
Heisenberg |
33 |
Inženýrství |
Rafferty |
31 |
Prodej |
Zaměstnanec „Williams“ a oddělení „Marketing“ se ve výsledcích provedení dotazu neobjeví. Ani jeden z nich nemá žádné odpovídající řádky v jiné příslušné tabulce: „Williams“ nemá žádné přidružené oddělení a žádný zaměstnanec nemá ID oddělení 35 („Marketing“). V závislosti na požadovaných výsledcích může být toto chování jemnou chybou, které lze zabránit nahrazením vnitřního spojení vnějším spojením.
Vnitřní spojení a NULL valuesEdit
Programátoři by měli zvláštní opatrnost při spojování tabulek ve sloupcích, které mohou obsahovat hodnoty NULL, protože NULL nikdy nebude odpovídat žádné jiné hodnotě (ani samotné NULL), pokud podmínka spojení výslovně nepoužívá predikát kombinace, který nejprve zkontroluje, zda jsou sloupce spojení NOT NULL
před použitím zbývajících predikátových podmínek. Vnitřní spojení lze bezpečně použít pouze v databázi, která vynucuje referenční integritu, nebo kde je zaručeno, že sloupce spojení nebudou NULL. Mnoho relačních databází zpracovávajících transakce spoléhá na standardy aktualizace dat Atomicity, Consistency, Isolation, Durability (ACID), aby byla zajištěna integrita dat, takže vnitřní spojení je vhodná volba. Transakční databáze však obvykle také mají žádoucí sloupce spojení, které mohou mít hodnotu NULL.Mnoho reportovacích relačních databází a datových skladů používá velkoobjemové dávkové aktualizace Extract, Transform, Load (ETL), které ztěžují nebo znemožňují vynucení referenční integrity, což má za následek potenciálně NULL spojení sloupců, které autor dotazu SQL nemůže upravit, a které způsobují vynechání vnitřních spojení data bez indikace chyby. Volba použití vnitřního spojení závisí na návrhu databáze a charakteristikách dat. Levé vnější spojení lze obvykle nahradit vnitřním spojením, když sloupce spojení v jedné tabulce mohou obsahovat hodnoty NULL.
Jakýkoli datový sloupec, který může být NULL (prázdný), by nikdy neměl být použit jako odkaz v vnitřní spojení, pokud není zamýšleným výsledkem vyloučení řádků s hodnotou NULL. Pokud mají být úmyslně odstraněny sloupce spojení NULL ze sady výsledků, může být vnitřní spojení rychlejší než vnější spojení, protože spojení tabulky a filtrování se provádí v jediném kroku. Naopak vnitřní spojení může mít za následek katastroficky pomalý výkon nebo dokonce selhání serveru, když se použije v dotazu na velký objem v kombinaci s databázovými funkcemi v klauzuli SQL Where. Funkce v klauzuli SQL Where může vést k tomu, že databáze ignoruje relativně kompaktní indexy tabulek. Databáze může číst a vnitřní spojení s vybranými sloupci z obou tabulek před snížením počtu řádků pomocí filtru, který závisí na vypočítané hodnotě, což vede k relativně enormnímu množství neefektivního zpracování.
Když je výsledková sada je produkováno spojením několika tabulek, včetně hlavních tabulek používaných k vyhledání úplných textových popisů číselných identifikačních kódů (vyhledávací tabulka), hodnota NULL v kterémkoli z cizích klíčů může mít za následek vyloučení celého řádku ze sady výsledků, bez indikace chyby. Složitý dotaz SQL, který zahrnuje jedno nebo více vnitřních spojení a několik vnějších spojení, má stejné riziko pro hodnoty NULL ve sloupcích odkazů na vnitřní spojení.
Závazek k kódu SQL obsahujícímu vnitřní spojení předpokládá, že sloupce spojení NULL nebudou budou zavedeny budoucími změnami, včetně aktualizací dodavatelů, změn designu a hromadného zpracování mimo pravidla pro ověřování dat aplikace, jako jsou převody dat, migrace, hromadné importy a slučování.
Vnitřní spojení lze dále klasifikovat jako equi-joins, jako přirozené spojení nebo jako cross-joins.
Equi-joinEdit
Equi-join je specifický typ spojení založeného na komparátoru, který používá pouze srovnání rovnosti v join-predicate. Použití jiných srovnávacích operátorů (například <
) diskvalifikuje join jako equi-join. Výše uvedený dotaz již poskytl příklad equi-join:
SELECT *FROM employee JOIN department ON employee.DepartmentID = department.DepartmentID;
Můžeme napsat equi-join, jak je uvedeno níže,
SELECT *FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Pokud spol lumns in an equi-join have the same name, SQL-92 provides an optional shorthand notation for expressing equi-joins, by by the USING
construct:
SELECT
read more