Join (SQL)

S Vikipedije, slobodne enciklopedije

SQL pridruživanje klauzula kombinuje zapise iz dve ili više tabela u referentne baze podataka. Kreira set koji može biti snimljen kao tabela ili iskorišćen takav kakav jeste. ПРИДРУЖИВАЊЕ je sredstvo za kombinovanje polja iz dve tabele (ili više) koristeći srodne vrednosti. ANSI-standard SQL određuje pet tipovaПРИДРУЖИВАЊА: УНУТРАШЊЕ, ЛЕВО СПОЉАШЊЕ, ДЕСНО СПОЉАШЊЕ, ПОТПУНО СПОЉАШЊЕ i УКРШТЕНО. Kao specijalan slučaj, tabela (bazna tabela, pregled, ili pridružena tabela) može придружити sebe u samopridruživanje.

Programer piše naredbu ПРИДРУЖИВАЊА za identifikaciju zapisa za pridruživanje. Ako je izračunati predikat tačan, kombinovani zapis je onda proizveden u očekivanom formatu, skup zapisa ili privremena tabela.

Probne tabele[uredi | uredi izvor]

Relacione baze podataka su obično normalizovane da eliminišu dupliranje podataka kao što su kada objekti imaju jednu-na-više relacija. Na primer , Odeljenje može biti povezano sa velikim brojem Zaposlenih. Pridruživanje razdvaja tabele za Odeljenje i Zaposlene i efektivno kreira drugu tabelu koja kombinuje informacije iz obe. Ovo je u neku štetu u smislu vremena koje je potrebno da se izračuna pridruživanje. A takođe je moguće da se jednostavno održava denormalizovana tabela ako je brzina bitna, duplirane informacije mogu uzeti dodatan prostor, i dodati troškove i složenost održavanja integriteta podataka ako se podaci koji su duplirani kasnije promene.

Sva naknadna objašnjenja o tipu pridruživanja u ovom artiklu su napravljena na osnovu sledeće dve tabele. Redovi u ovim tabelama služe da ilustruju efekat različitih tipova pridruživanja i predikata pridruživanja. U narednim tabelama ОдељењеИД kolona tabele Одељења (koja se može označiti kao Одељење.ОдељењеИД) je primarni ključ, dok je Запослени.ОдељењеИД Strani ključ.

Tabela zaposlenih
Prezime OdeljenjeID
Raferti 31
Džouns 33
Haizenberg 33
Robinson 34
Smit 34
Viliams NULL
Tabela odeljenja
OdeljenjeID OdeljenjeNaziv
31 Rasprodaja
33 Inženjeri
34 Sveštenici
35 Marketing

Napomena: U tabeli Zaposlenih iznad, zaposleni "Viliams" nije još dodeljen nijednom odeljenju. Takođe, primetite da nema zaposlenih dodeljenih "Marketing" odeljenju .

Ovo je SQL naredba za kreiranje navedenih tabela.

CREATE TABLE одељење
(
 ОдељењеИД INT,
 ОдељењеНазив VARCHAR(20)
);

CREATE TABLE запослени
(
 Презиме VARCHAR(20),
 ОдељењеИД INT
);

INSERT INTO одељење VALUES(31, 'Распродаја');
INSERT INTO одељење VALUES(33, 'Инжењери');
INSERT INTO одељење VALUES(34, 'Свештеници');
INSERT INTO одељење VALUES(35, 'Маркетинг');

INSERT INTO запослени VALUES('Раферти', 31);
INSERT INTO запослени VALUES('Џоунс', 33);
INSERT INTO запослени VALUES('Хаизенберг', 33);
INSERT INTO запослени VALUES('Робинсон', 34);
INSERT INTO запослени VALUES('Смит', 34);
INSERT INTO запослени VALUES('Вилиамс', NULL);

Ukršteno pridruživanje[uredi | uredi izvor]

UKRŠTENO PRIDRUŽIVANjE vraća Dekartov proizvod redova tabele pridruživanja. Drugim rečima, proizvešće redove koji kombinuju svaki red prve tabele sa svakim redom druge tabele.[1]

Primer eksplicitnog ukrštenog pridruživanja:

SELECT *
FROM запослени CROSS JOIN одељење;

Primer implicitnog ukrštenog pridruživanja:

SELECT *
FROM запослени, одељење;
Zaposleni.Prezime Zaposleni.OdeljenjeID Odeljenje.OdeljenjeNaziv Odeljenje.OdeljenjeID
Raferti 31 Rasprodaja 31
Džouns 33 Rasprodaja 31
Haizenberg 33 Rasprodaja 31
Smit 34 Rasprodaja 31
Robinson 34 Rasprodaja 31
Viliams NULL Rasprodaja 31
Raferti 31 Inženjeri 33
Džouns 33 Inženjeri 33
Haizenberg 33 Inženjeri 33
Smit 34 Inženjeri 33
Robinson 34 Inženjeri 33
Viliams NULL Inženjeri 33
Raferti 31 Sveštenici 34
Džouns 33 Sveštenici 34
Haizenberg 33 Sveštenici 34
Smit 34 Sveštenici 34
Robinson 34 Sveštenici 34
Viliams NULL Sveštenici 34
Raferti 31 Marketing 35
Džouns 33 Marketing 35
Haizenberg 33 Marketing 35
Smit 34 Marketing 35
Robinson 34 Marketing 35
Viliams NULL Marketing 35

Ukršteno pridruživanje ne primenjuje predikat za filtriranje podataka iz tabele pridruživanja. Rezultat ukrštenog pridruživanja može biti filtriran koristeći WHERE klauzulu koja može proizvesti ekvivalent unutrašnjeg pridruživanja.

U SQL:2011 standardu, ukrštena pridruživanja su deo opcionog F401, "Tabela produženog pridruživanja", paketa.

Normalna upotreba je za proveravanje performansi servera.

Prirodno pridruživanje ()[uredi | uredi izvor]

Prirodno pridruživanje () je binarna operacija koja se zapisuje kao (R S) gde su R i S relacije.[2] Rezultat prirodnog pridruživanja je set svih kombinacija od torki u R i S koji su jednaki uobičajenim imenima njihovih atributa. Na primer razmotrimo tabele Zaposleni and Odeljenje i njihovo prirodno pridruživanje:

Zaposleni
Ime ZapID OdeljenjeIme
Heri 3415 Finansije
Seli 2241 Rasprodaja
Džordž 3401 Finanasije
Heriet 2202 Rasprodaja
Odeljenje
OdeljIme Menadžer
Finansije Džordž
Rasprodaja Heriet
Proizvodnja Čarls
Zaposleni Odeljenje
Ime ZapID OdeljenjeIme Menadžer
Heri 3415 Finansije Džordž
Seli 2241 Rasprodaja Hariet
Džordž 3401 Finansije Džordž
Hariet 2202 Rasprodaja Hariet

Ovo takođe može biti iskorišćeno za definisanje kompozicije relacija. Na primer, kompozicija Zaposleni and Odeljenje je njihovo pridruživanje kao što je prikazano gore, projektovano na sve sem zajedničkog atributa OdeljenjeNaziv. U teoriji kategorije, pridruživanje je upravo produkat vlakana.

Prirodno pridruživanje je verovatno jedna od najbitnijih operacija jer je relacioni pandan logičkom I. Primetite pažljivo da ako se ista promenljiva pojavljuje u svakom od dva predikata koji su povezani sa I, onda se ta promenljiva zalaže za istu stvar i oba pojavljivanja moraju biti zamenjena istom vrednošću. Konkretno, prirodno pridruživanje omogućuje kombinaciju relacija koje su povezane stranim ključem. Na primer, u gornjem primeru strani ključ verovatno razdvaja Zaposleni.OdeljenjeNaziv i Odeljenje.OdeljenjeNaziv i onda prirodno pridruživanje Zaposlenih i Odeljenja kombinuje sve zaposlene sa njihovim odeljenjem. Primetite da ovo funkcioniše zato što strani ključ stoji između atributa sa istim imenom. Ako ovo nije slučaj da je strani ključ između Odeljenje.menadžer i Zaposleni.Ime onda moramo da preimenujemo kolone pre nego što primenimo prirodno pridruživanje. Takvo pridrživanje se ponekad poistovećuje sa izjednačenim pridruživanjem.

Više formalne semantike prirodnog pridruživanja je definisano na sledeći način:

gde je Fun predikat koji je tačan za relaciju r Ako i samo ako je r funkcija. Obično se zahteva da R i S imaju bar jednu zajedničku osobinu, ali ako se izostavi ovo ograničenje, i R i S nemaju zajedničku osobinu, onda prirodno pridruživanje postaje baš Dekartov proizvod.

Prirodno pridruživanje može biti simulirano sa Codd's primitives na sledeći način. Pretpostavimo da su c1,...,cm imena atributa zajednička za R i S, r1,...,rn su imena atributa jedinstvena za R i s1,...,sk su atributi jedinstveni za S. Štaviše, pretpostaviti da imena atributa x1,...,xm nisu ni u R ni u S. U prvom koraku mi sada možemo preimenovati zajednička imena atributa u S:

Onda ćemo uzeti Dekartov proizvod i izabrati one vrste koje treba pridružiti:

Konačno uzimamo projekciju kako bi se otarasili preimenovanih atributa:

Prirodno pridruživanje je specijalan slučaj izjednačenog pridruživanja koje je specijalan slučaj unutrašnjeg pridruživanja kao što je opisano u Prirodnom pridruživanju.

Unutrašnje pridruživanje[uredi | uredi izvor]

Unutrašnje pridruživanje zahteva da svaki podatak iz dve povezane tabele ima podatak sa kojim je povezan, i obično je korisna operacija u aplikacijama ali nije zasigurno najbolji izbor u svim situacijama. Unutrašnje pridruživanje kreira novu rezultujuću tabelu kombinovanjem vrednosti kolona dve tabele (A i B) zasnovanim na predikatima pridruživanja. Upit poredi svaki red iz A sa svakim redom iz B kako bi našao sve parove redova koji zadovoljavaju predikat pridruživanja. Kada je predikat pridruživanja zadovoljen odgovarajućim ne-nula vrednostima, vrednosti kolona za svaki odgovarajući par redova A i B se kombinuju u rezultujući red.

Rezultat pridruživanja može biti definisan kao ishod uzimanja Dekartovog proizvoda (ili ukrštenog pridruživanja) svih podataka tabele (kombinovanje svakog podatka iz tabele A sa svakim podatkom iz tabele B) i zatim se vraćaju svi podaci koji zadovoljavaju predikat pridruživanja. Aktuelne SQL implementacije normalno koriste i druge pristupe, kao što je [[heš pridruživanje ili pridruživanje sortiranje spajanjem, od ere kompjutera Dekartov proizvod je sporiji i često će zahtevati nedopustivo veliki memorijski prostor za skladišćenje.

SQL navodi dva različita sintaksna načina da izrazi pridruživanja: "eksplicitna notacija pridruživanja" i "implicitna notacija pridruživanja". Takođe "implicitna notacija pridruživanja" je prevaziđena u 1992, i njena upotreba se ne smatra najboljom praksom, ipak baza podataka je i dalje podržava.

"Eksplicitna notacija pridruživanja" koristi JOIN ključnu reč, opciono prethodi ključnoj reči INNER, da odredi tabelu pridruživanja, i ON ključna reč da odredi predikate za pridruživanje, kao u narednom primeru:

SELECT *
FROM запослено
INNER JOIN одељење ON запослени.ОдељењеИД = одељење.ОдељењеИД;

"Implicitna notacija pridruživanja" jednostavno lista tabele za pridruživanja, u FROM klauzuli izjave SELECT, koristeći zareze da ih razdvoji. Tako se precizira ukršteno pridruživanje, i WHERE klauzula može aplicirati dodatne filter-predikate (koja funkcija je uporediva sa predikatima pridruživanja u eksplicitnoj notaciji).

Naredni primer je ekvivalentan prethodnom, ali ovaj put u implicitnoj notaciji:

SELECT *
FROM запослени, одељење
WHERE запослени.ОдељењеИД = одељење.ОдељењеИД;

Upiti dati u primerima iznad će pridružiti tabele Zaposleni i Odeljenje koristeći OdeljenjeID kolonu obe tabele. Gde se OdeljenjeID ovih tabela podudara (tj. predikat pridruživanja je zadovoljen), upit će kombinovati Prezime, Odeljenje i OdeljenjeNaziv kolone iz dve tabele u rezultujući red. Gde se OdeljenjeID ne podudara, rezultujući red neće biti generisan.

Tako će rezultat izvršenja bilo koja od dva upita iznad biti:

Zaposleni.Prezime Zaposleni.OdeljenjeID Odeljenje.OdeljenjeIme Odeljenje.OdeljenjeID
Robinson 34 Sveštenici 34
Džouns 33 Inženjeri 33
Smit 34 Sveštenici 34
Haizenberg 33 Inženjeri 33
Raferti 31 Rasprodaja 31

Primetimo da se zaposleni "Viliams" i odeljenje "Marketing" ne pojavljuju u rezultatima izvršenja upita. Ni jedno od njih nema podudaranja zapisa u drugoj odgovarajućoj tabeli: "Viliams" nema povezano odeljenje, i nema zaposlenih sa odeljenjem ID 35 ("Marketing"). Zavisno od željenih rezultata, ovo ponašanje može biti suptilna greška, koja se može izbeći zamenom unutrašnjeg pridruživanja sa spoljašnjim.

Primetiti: Programeri bi trebalo posebno da obrate pažnju kada tabele pridruživanja u kolonama mogu da sadrže NULL vrednosti, dok NULL neće nikada odgovarati bilo kojoj drugoj vrednosti (ni samoj nuli), osim ako uslov pridruživanja eksplicitno koristi kombinaciju predikata koji prvo proveravaju da li su polja pridruživanja NOT NULL pre primene preostalih predikata uslova. Unutrašnje pridruživanje može jedino biti sigurno iskorišćen u bazama podataka koje sprovode Referencijalni integritet ili gde polja pridruživanja garantovano nisu NULL. Mnoge obrade transakcija relacionih baza podataka oslanjaju se na ACID standard ažuriranja podataka kako bi osigurali integritet podataka, gde unutrašnje pridruživanje postaje odgovarajući izbor. Međutim transakcija baza podataka obično ima poželjna polja pridruživanja kojima je dozvoljeno da budu NULL. Mnoge izveštajne relacione baze podataka i skladišta podataka koriste visok opseg Extract, Transform, Load (ETL) batch updates koji čine referencijalni integritet teškim ili nemogućim za sprovođenje, rezultuje potencijalna NULL polja pridruživanja koja autor SQL upita ne može da modifikuje i uzrokuje da unutrašnje pridruživanje izostavi podatke bez indikacije o grešci. Izbor unutrašnjeg pridruživanja zavisi od dizajna baze podataka i karakteristike podataka. Levo spoljašnje pridruživanje može biti zamenjeno unutrašnjim kada polje pridruživanja u jednoj tabeli može sadržati NULL vrednosti.

Bilo koje polje podatka koje može biti NULL (prazno) ne bi trebalo nikad da bude upotrebljeno kao veza u unutrašnjem pridruživanju, osim ako je željeni rezultat da se eliminišu podaci sa NULL vrednošću. Ako su NULL polja pridruživanja namerno uklonjena iz skupa rezultata,unutrašnje pridruživanja može biti brže od jednog spoljašnjeg zato što tabela pridruživanja i filtriranje se obavlja u jednom koraku. Suprotno, unutrašnje pridruživanja može rezultirati katastrofalnom smanjivanju performansi ili čak padom servera pri korišćenju velikog opsega upita u kombinaciji sa funkcijama baze podataka u SQL Where klauzuli.[3][4][5] Funcija u SQL Where klauzuli može rezultirari u bazi podataka ignorisanjem relativno kompaktnih indeksa tabele. Baza podataka može čitati i selektovana polja unutrašnjeg pridruživanja iz obe tabele pre redukovanja broja redova koristeći filter koji zavisi od izračunate vrednosti, što rezultira relativno ogromnoj količini neefikasne obrade.

Kada je rezultujući skup proizveden pridruživanjem više tabela, uključujući master tabele koje se koriste za traženje celokupnog tekstualnog opisa numeričkih identifikacionih kodova (Lukap tabela), a NULL vrednosti u bilo kom od stranih ključeva može rezultirati da se ceo red eliminiše iz rezultujućeg skupa, bez indikacije o grešci. Kompleks SQL upita koji uključuju jedan ili više unutrašnjih pridruživanja i nekoliko spoljašnjih imaju isti rizik za NULL vrednosti u link poljima spoljašnjeg pridruživanja.

Posvećenost SQL kodu sadrži pretpostavku unutrašnjeg pridruživanja da NULL polja pridruživanja neće biti uvedena budućim promenama, uključujući vendor updates, promene dizajna i glavno procesiranje van pravila valjanosti aplikacionih podataka kao što su konverzije podataka, migracije, bulk uključivanja i stapanja.

Može se dalje klasifikovati unutrašnje pridruživanja kao izjednačeno pridruživanje, kao prirodno pridruživanja, ili kao ukršteno pridruživanja.

Izjednačeno pridruživanje[uredi | uredi izvor]

Izjednačeno pridruživanje je specijalan tip pridruživanja baziranog na komparatoru, koji koristi samo jednakost poređenja u predikatu pridruživanja. Koristeći druge operatore poređenja (kao što je <) diskvalifikuje pridruživanje kao izjednačeno pridruživanje. Upit prikazan gore već predctavlja primer jednog izjednačenog pridruživanja:

SELECT *
FROM запослени JOIN одељење
  ON запослени.ОдељењеИД = одељење.ОдељењеИД;

Možemo pisati izjednačeno pridruživanje kao ispod,

SELECT *
FROM запослени, одељење
WHERE запослени.ОдељењеИД = одељење.ОдељењеИД;

Ako kolone u izjednačenom pridruživanja imaju isto ime, SQL-92 dopušta opcionu skraćenu notaciju za izražavanje izjednačenog pridruživanja, putem USING konstrukta:[6]

SELECT *
FROM запослени INNER JOIN одељење USING (DepartmentID);

USING konstrukt je više od samog sintaktičkog šećera (syntactic sugar), ma kako, jer se rezultujući skup razlikuje od rezultujućeg skupa verzije sa eksplicitnim predikatom. Posebno, bilo koje kolone pomenute u USING listi će se pojaviti samo jednom, sa nekvalifikovanim imenom, a po jednom za svaku tabelu u pridruživanju. U slučaju iznad, biće samo ОдељењеИД kolona a ne запослени.ОдељењеИД ili одељење.ОдељењеИД.

USING klauzula nije podržana od strane MS SQL Server i Sybase.

Prirodno pridruživanje[uredi | uredi izvor]

Prirodno pridruživanje je vrsta podjednakog pridruživanja gde join predikat nastaje implicitno poređenjem svih kolona u obe tabele koje imaju isti naziv kolone u povezanoj tabeli. Rezultujuća povezana tabela sadrži samo jednu kolonu za svaki par kolona sa istim nazivom. U slučaju da nema kolona sa istim nazivom onda se koristi ukršteno pridruživanje.

Mnogi eksperti smatraju da je PRIRODNO PRIDRUŽIVANjE opasno i obeshrabruje njihovu upotrebu.[7] Opasnost dolazi od namernog dodavanja nove kolone, imenovane isto kao druga kolona u drugoj tabeli. U postojećem prirodnom pridruživanju on će "prirodno" da koristi novu kolonu za poređenje, vršeći poređenje koristeći drugačije kriterijume (od različitih kolona) nego ranije. Tako postojeći upit može proizvesti različite rezultate, iako podaci u tabeli nisu promenjeni, ali jeste argument. Upotreba imena kolona da se automatski odredi veze između tabela nije dobra opcija u velikim bazama podataka sa stotine ili hiljade tabela. U realanom svetu baza podataka su uglavnom dizajnirane sa Strani ključ podacima koji nisu doslovno popunjeni (NULL vrednosti su dozvoljene), zbog pravila poslovanja. To je uobičajena praksa da se modifikuju imena kolona sličnih podataka u različitim tabelama i ovaj nedostatak prirodnog pridruživanja je teoretski koncept za diskusiju.

Gornji primer upita za unutrašnje pridruživanje može se objasniti kao prirodno pridruživanje na sledeći način:

SELECT *
FROM запослени NATURAL JOIN одељење;

Kao i kod eksplicitnog korišćenja USING klauzule, samo jedna OdeljenjeID kolona se javlja u pridruženoj tabeli:

OdeljenjeID Zaposleni.Prezime Odeljenje.OdeljenjeNaziv
34 Smit Sveštenici
33 Džouns Inženjeri
34 Robinson Sveštenici
33 Haizenberg Inženjeri
31 Raferti Rasprodaja

PostgreSQL, MySQL i Oracle podržavaju prirodno pridruživanje; Microsoft T-SQL i IBM DB2 ne podržavaju. Kolone koje se koriste u pridruživanju su implicitne pa kod pridruživanja ne prikazuje očekivane kolone, i promene u nazivu kolona mogu da promene razultat. U SQL:2011 standardu, prirodno pridruižvanje je deo opcije F401, "Proširene tabele pridruživanja", paketa.

U mnogim okruženjima baza podataka imena kolona su kontrolisana spoljašnjom pomoću, a ne upitom programera. Prirodno pridruživanje pretpostavlja stabilnost i konzistentnost naziva kolona koje može da se proemni nadogradnjom verzije.

Spoljašnje pridruživanje[uredi | uredi izvor]

Pridružene tabele zadržavaju svaki podatak—čak iako ne postoji ni jedan drugi povezani podatak. Spoljašnje pridruživanje se dalje deli na levo spoljašnje, desno spoljašnje pridruživanje i potpuno spoljašnje pridruživanje, što zavisi koji redovi tabele su zadržani (levi, desni, ili oba).

(U slučaju levo i desno odnosi se na dve strane JOIN ključne reči.)

Ne postoji implicitna notacija za spoljašnje pridruižvanje u standardu SQL.

Levo spoljašnje pridruživanje[uredi | uredi izvor]

Rezultat levog spoljašnjeg pridruživanja (ili jednostavno levo pridruživanje) za tabele A i B uvek sadrži sve podatke o “levoj” tabeli (A), čak iako se po uslovu-pridruživanja ne poklapa sa podacima u “desnoj” tabeli (B). Ovo znači i ako klauzula ON pronađe 0 podataka u B (za zadati podatak iz A), pridruživanje će svakako vratiti red kao rezultat (za taj podatak) - ali sa NULL u svakoj koloni za B. Levo spoljašnje pridruživanje vraća sve vrednosti iz unutrašnjeg pridruživanjaa plus sve vrednosti iz leve tabele koje nisu povezane sa desnom tabelom, uključujući redove sa NULL (prazne) vrednostima.

Na primer to nam omogućava da pronađemo odeljenje zaposlenih, ali i dalje prikazuje zaposlene koji nisu pridruženi odeljenju (za razliku od unutrašnjeg pridruživanja primer gore, gde nepridruženi nisu bili u rezultatu).

Primer levog spoljašnjeg pridruživanja Primer levog spoljašnjeg pridruživanja ( СПОЉАШЊЕ ključna reč je opciona), sa dodatnim rezultatima reda (u poređenju sa unutrašnjim pridruživanjem) su iskošeni:

SELECT *
FROM запослени 
LEFT OUTER JOIN одељење ON запослени.ОдељењеИД = одељење.ОдељењеИД;
Zaposleni.Prezime Zaposleni.OdeljenjeID Odeljenje.OdeljenjeNaziv Odeljenje.OdeljenjeID
Džouns 33 Inženjeri 33
Raferti 31 Rasprodaja 31
Robinson 34 Sveštenici 34
Smit 34 Sveštenici 34
Viliams NULL NULL NULL
Haizenberg 33 Inženjeri 33

Alternativne sintakse[uredi | uredi izvor]

Oracle podržava zastarelu[8] sintaksu:

SELECT *
FROM запослени, одељење
WHERE запослени.ОдељењеИД = одељење.ОдељењеИД(+)

Sybase podržava sintaksu (Microsoft SQL Server starija sintaksa od verzije 2000):

SELECT *
FROM запослени, одељење
WHERE запослени.ОдељењеИД *= одељење.ОдељењеИД

IBM Informix podržava sintaksu:

SELECT *
FROM запослени, OUTER одељење
WHERE запослени.ОдељењеИД = одељење.ОдељењеИД

Desno spoljašnje pridruživanje[uredi | uredi izvor]

Desno spoljašnje pridruživanje (ili desno pridruživanje) liči na levo spoljašnje pridruživanje, osim što tabele tretira obrnuto. Svaki red iz "desne" tabele (B) će se pojaviti u pridruženoj tabeli barem jednom. Ukoliko postoje nepovezani redovi iz "leve" tabele (A), NULL će se pojaviti u koloni iz A za one podatke koji nisu povezani sa B.

Desno spoljašnje pridruživanje vraća sve vrednosti iz desne tabele i povezane vrednosti iz leve tabele (NULL u slučaju da nije povezan pridružuje predikat). Na primer, ovo nam omogućava da nađemo zaposlene i njegovo ili njeno odeljenje, ali i dalje pokazuje odeljenja koje nemaju zaposlene.

Ispod je primer desno spoljašnjeg pridruživanja (СПОЉАШЊЕ ključna reč je opciona), sa dodatnim redom rezultata koji je iskošen:

SELECT *
FROM запослени RIGHT OUTER JOIN одељење
  ON запослени.ОдељењеИД = одељење.ОдељењеИД;
Zaposleni.Prezime Zaposleni.OdeljenjeID Odeljenje.OdeljenjeNaziv Odeljenje.OdeljenjeID
Smit 34 Sveštenici 34
Džouns 33 Inženjeri 33
Robinson 34 Sveštenici 34
Haizenberg 33 Inženjeri 33
Raferti 31 Rasprodaja 31
NULL NULL Marketing 35

Desno i levo spoljašnje pridruživanje su funkcionalno jednaki. Ni jedan nema neku funkciju koju drugi nema, tako da desno i levo spoljašnje pridruživanje mogu da zamene jedno drugo sve dok je redosled u tabeli obrnut.

Potpuno spoljašnje pridruživanje[uredi | uredi izvor]

Konceptualno, potpuno spoljašnje pridruživanje kombinuje efekte od primene oba i levog i desnog spoljašnjeg pridruživanja. Gde podaci u tabeli potpunog spoljašnjeg pridruživanja nisu povezani, rezultat će imati NULL vrednost za svaku kolonu u tabeli gde nedostsaje povezani red. Za te podatke koji se poklapaju, rezultata će biti jedna linija (sadrži polja iz obe tabele).

Na primer, ovo nam omogućava da vidimo svakog zaposlenog koji je u odeljenju i svako odeljenje koje ima nekog zaposlenog, ali i da vidimo svakog zaposlenog koji nije deo odeljenja i svko odeljenje koje nema zaposlenog.

Primer totalnog spoljašnjeg pridruživanja (СПОЊАШЊЕ ključna reč je opciona):

SELECT *
FROM запослени FULL OUTER JOIN одељење
  ON запослени.ОдељењеИД = одељење.ОдељењеИД;
Zaposleni.Prezime Zaposleni.OdeljenjeID Odeljenje.OdeljenjeNaziv Odeljenje.OdeljenjeID
Smit 34 Sveštenici 34
Džouns 33 Inženjer 33
Robinson 34 Sveštenici 34
Viliams NULL NULL NULL
Haizenberg 33 Inženjer 33
Raferti 31 Rasprodaja 31
NULL NULL Marketing 35

Neke baze podataka ne podržavaju funkcije totalnog spoljašnjeg pridruživanja direktno, ali mogu da simuliraju to kroz upotrebu unutrašnjeg pridruživanja i UNION ALL selektora za "pojedinačni red tabele" od leve i desne tabele redom. Isti primer može da se prikaže na sledeći način:

SELECT запослени.Презиме, запослени.ОдељењеИД,
       одељење.ОдељењеНазив, одељење.ОдељењеИД
FROM запослени
INNER JOIN одељење ON одељење.ОдељењеИД = одељење.ОдељењеИД

UNION ALL

SELECT запослени.Презиме, запослени.ОдељењеИД,
       cast(NULL as varchar(20)), cast(NULL as integer)
FROM запослени
WHERE NOT EXISTS (
    SELECT * FROM одељење
             WHERE запослени.ОдељењеИД = одељење.ОдељењеИД)

UNION ALL

SELECT cast(NULL as varchar(20)), cast(NULL as integer),
       одељење.ОдељењеНазив, одељење.ОдељењеИД
FROM одељење
WHERE NOT EXISTS (
    SELECT * FROM запослени
             WHERE запослени.ОдељењеИД = одељење.ОдељењеИД)

Samopridruživanje[uredi | uredi izvor]

Samopridruživanje pridružuje tabelu sebi.[9]

Primer[uredi | uredi izvor]

Ukoliko imamo dve odvojene tabele za zaposlene i pitanje koje zahteva zaposlenog u prvoj tabeli koji ima istu državu kao i zaposlen u drugoj tabeli, normalno pridruživanje može da se koristi za nalaženje odgovora. Svakako, sve informacije za zaposlenog se nalaze u jednoj velikoj tabeli.[10]

Razmislite o modifikovanju Запослени tabele kao u narednom delu:

Tabela zaposlenih
ZaposleniID Prezime Država OdeljenjeID
123 Raferti Australija 31
124 Džouns Australija 33
145 Haizenberg Australija 33
201 Robinson Sijedinjene Države 34
305 Smit Nemačka 34
306 Viliams Nemačka NULL

Primer rešenja upita može biti kao u nastavku:

SELECT F.ЗапослениИД, F.Презиме, S.ЗапослениИД, S.Презиме, F.Држава
FROM Запослени F INNER JOIN Запослени S ON F.Држава = S.Држава
WHERE F.ЗапослениИД < S.ЗапослениИД
ORDER BY F.ЗапослениИД, S.ЗапослениИД;

Čiji rezultat se generiše narednom tabelom.

Tabela Zaposlenih nakon samopridruženja po državi
ZaposleniID Prezime ZaposleniID Prezime Država
123 Raferti 124 Džouns Australija
123 Raferti 145 Haizenberg Australija
124 Džouns 145 Haizenberg Australija
305 Smit 306 Viliams Nemačka

Za ovaj primer:

  • F i S su pseudonimi za prvu i drugu kopiju tabele zaposlenih.
  • Uslov F.Држава = S.Држава isključuje uparivanje između zaposlenih iz suprotnih država. Zadato pitanje želi parove zaposlenih iz iste države.
  • Uslov F.ЗапослениИД < S.ЗапослениИД isključuje uparivanje gde je ЗапослениИД od prvog zaposlenog veći ili jednak ЗапослениИД sa drugim zaposlenim. Drugim rečima, efekat ovog uslova je da isključi duplo uparivanje i samouparivanje. Bez toga, sledeća manje korisna tabela bila bi generisana (tebla ispod prikzuje samo "Nemačka" deo rezultata):
ZaposleniID Prezime ZaposleniID Prezime Država
305 Smit 305 Smit Nemačka
305 Smit 306 Viliams Nemačka
306 Viliams 305 Smit Nemačka
306 Viliams 306 Viliams Nemačka

Samo jedno od dva srednja uparenja su dovoljna da zadovolje pitanje, i skroz gornja i skroz donja su nepotrebna za ovaj primer.

Alternative[uredi | uredi izvor]

Efekat spoljašnjeg pridruživanja može se dobiti korišćenjem UNION ALL između INNER JOIN i SELECT od redova u "glavnoj" tabeli koji ne upotpunjuju uslove pridruživanja. Na primer,

SELECT запослени.Презиме, запослени.ОдељењеИД, одељење.ОдељењеНазив
FROM запослени
LEFT OUTER JOIN одељење ON запослени.ОдељењеИД = одељење.ОдељењеИД;

može se takođe zapisati kao

SELECT запослени.Презиме, запослени.ОдељењеИД, одељење.ОдељењеНазив
FROM запослени
INNER JOIN одељење ON запослени.ОдељењеИД = одељење.ОдељењеИД

UNION ALL

SELECT запослени.Презиме, запослени.ОдељењеИД, cast(NULL as varchar(20))
FROM запослени
WHERE NOT EXISTS (
    SELECT * FROM одељење
             WHERE запослени.ОдељењеИД = одељење.ОдељењеИД)

Implementacija[uredi | uredi izvor]

Dosta posla u sistemu baza podataka imaju za cilj efikasnu implementaciju za pridruživanje, jer relacioni sistemi obično traže pridruživanje, ali se suočavaju sa poteškoćama u optimizaciji za efikasno izvršavanje. Problem nastaje jer unutrašnje povezivanje operišse sa oba Komutativnost i Asocijativnost. U praksi, to znači da korisnik samo snabdeva listu tabela za pridruživanje i uslove pridruživanja koji se koriste, a sistem baza podataka ima zadatak da pronađe najefikasniji način da izvrši operaciju. Optimizacija upita određuje kako da se izvrši upit koji sadrži pridruživanje. Optimizator upita ima dve osnovne slobode:

  1. Redosled pridruživanja: Zato što funkcije spaja kommutativno i asocijativno, redosled kojim sistem pridružuje tabele ne menja krajnje rešenje upita. Svakako, redosled pridruživanja može imati ogroman uticaj na cenu operacije pridruživanja, tako da izbor najboljeg redposleda pridruživanja postaje jako bitan.
  2. Metode pridruživanja: Za date dve tabele i uslove pridruživanja, više Algoritam mogu da proizvedu rezultat pridruživanja. Koji algoritam radi najefikasnije zavisi od veličine unosa u tabeli, broj redova za svaku tabelu koji ispunjavaju uslov pridruživanja, i operacija koje zahteva ostatak upita.

Mnogi algoritmi upoređenja tretiraju svoj doprinos različito. Može se odnositi na ulaze za pridruživanje kao i "spoljašnje" i "unutrašnje" operacije pridruživanja, ili "levo" i "desno", redom. U slučaju grupisanih petlji, na primer, sistem baza podataka će skenirati unos unutrašnjih relacija za svaki red spoljašnje relacije.

Jedan od njih može svrstati plan-upita uključujući pridruživanje kao u nastavku:[11]

levo-duboko
koristi osnovnu tabelu (radije nego ostala pridruživanja) kao unutrašnji operand za svako pridruživanje iz upita
desno-duboko
koristi osnovnu tabelu kao spoljašnji operand za svako pridruživanje iz upita
žbunasto
ni levo-duboko ni desno-duboko; oba ulaza za pridruživanje mogu rezultirati pridruživanjem

Ova imena su izvedena od pojave Plan upita nacrtano kao Stablo (struktura podataka), sa relacijom spoljašnjeg pridruživanja na levoj i unutrašnjeg na desnoj (kako nalaže konvencija).

Algoritmi pridruživanja[uredi | uredi izvor]

Postoje tri osnovna algoritma za operacije pridruživanja: Pridruživanje ukrštene petlje, Prudruživanje sortiranje spajanjem and Heš pridruživanje.

Indeksi pridruživanja[uredi | uredi izvor]

Indeksi pridruživanja su Indeksi baza podataka koji olakšavaju obradu upita pridružovanja u skladištu podataka: oni su trenutno (2012) dostupni u implementacijama Orakl[12] i Teradata.[13]

U implementaciji Teradata, navedene kolone, sveobuhvatna funkcija za kolone, ili komponente od kolone datuma iz jedne ili više tabela su navede korišćenjem sintakse slične definiciij Pregled baza podataka: Do 64 kolona/kolone izraza mogu biti navedeni u jednom indeks pridruživanju. Opciono, kolona koja definiše Primarni ključ kompozicionog podatka može takođe da bude naveden: na paralelnom hardveru, vrednosti kolone se koriste za podelu sadržaja indeksa na više diskova. Kada se izvorne tabele ažuriraju interaktivno od strane korisnika, sadržaj indeksa pridruživanja će biti automatski ažurirani. Bilo koji upit čiji WHERE klauzula precizira bilo koju kombinaciju kolona ili kolona izraza koji je tačno onaj podskup koji je definisan u indeksu pridruživanja (tzv "prekriveni upit") će dovesti do indeksa pridruživanja, pre nego originalne tabele i njihovi indeksi, da budu konsultovani u toku izvršavanja upita.

Oracle implementacije su limitirane da koriste bitmap indekse. bitmap indeksi se koriste za kolone sa malim sadržajem (tj, kolona koje sadrže malo više od 300 različitih vrednosti, u skladu sa Oracle dokumentacijom): ona kombinuje kolone sa malim sadržajem od više povezanih tabela. Primer upotrebe Oracle je u sistemu inventar, gde različiti dobavljači obezbeđuju različite delove. Šema ima tri povezane tabele: dve "master tabele", Deo i Dobavljač, i "tabela detalja", Inventar. Poslednji je više i više tabela povezivanja Dobavljač za Deo, i sadrži najviše redova. Svaki deo sadrži i tip dela, i svaki dobavljač ja osnovan u SAD, i ima kolonu Države. Ne postoji više od 60 država-teritorija u SAD, i ne više od 300 tipova delova. Bitmap indeksi pridruživanja je definisano upotrebom standardnog pridruživanja tri-tabele na tri gornje tabele, i definiše Deo_Tip i Dobavljač_Država kolone za indekse. Svakako, to je definisano na tabeli Inventara, iako su kolonoe Deo_Tip i Dobavljač_Država "pozajmljene" od Dobavljač i Deo.

Kao i za Teradata, Oracle bitmap indeksi pridruživanja se koriste da odgovore na upit kada WHERE klauzula precizira kolone ograničene na one koje su uključene u indeksu pridruživanja.

Direktno pridruživanje[uredi | uredi izvor]

Neki sistemi baza podataka dozvoljavaju korisniku da natera sistem da čita tabele u pridruživanju u određenom redosledu. Ovo se koristi kada optimizator pridruživanja izabere da čita tabele i neefikasnom redosledu. Na primer, u MySQL komanda STRAIGHT_JOIN uradi unutrašnje pridruživanje ali čita tabele tačno u redsledu kojim su navedene u upitu.[14]

Vidi još[uredi | uredi izvor]

Reference[uredi | uredi izvor]

  1. ^ SQL CROSS JOIN
  2. ^ In Unicode, the bowtie symbol is ⋈ (U+22C8).
  3. ^ Greg Robidoux, "Avoid SQL Server functions in the WHERE clause for Performance", MSSQL Tips, 5/3/2007
  4. ^ Patrick Wolf, "Inside Oracle APEX "Caution when using PL/SQL functions in a SQL statement", 11/30/2006
  5. ^ Gregory A. Larsen, "T-SQL Best Practices - Don't Use Scalar Value Functions in Column List or WHERE Clauses", 10/29/2009,
  6. ^ Simplifying Joins with the USING Keyword
  7. ^ Ask Tom "Oracle support of ANSI joins." Back to basics: inner joins » Eddie Awad's Blog Arhivirano na sajtu Wayback Machine (19. novembar 2010)
  8. ^ Oracle Left Outer Join
  9. ^ Shah 2005, str. 165
  10. ^ Adapted from Pratt 2005, str. 115–6
  11. ^ Yu & Meng 1998, str. 213
  12. ^ Oracle Bitmap Join Index. URL: http://www.dba-oracle.com/art_builder_bitmap_join_idx.htm
  13. ^ Teradata Join Indexes. http://www.coffingdw.com/sql/tdsqlutp/join_index.htm Arhivirano na sajtu Wayback Machine (16. decembar 2012)
  14. ^ „13.2.9.2 JOIN Syntax”. MySQL 5.7 Reference Manual. Oracle Corporation. Pristupljeno 03. 12. 2015. 

Literatura[uredi | uredi izvor]

Spoljašnje veze[uredi | uredi izvor]