4. Extragerea datelor din mai multe tabele

In acest captiol ne propunem sa prezentam mijloacele prin care se pot obtine date din mai multe tabele; conceptul care sta labaza acestui rezultat
este join-ul.Pe langa join-ul dintre mai multe tabele diferite, exista si asa numitul "self join" ("autojoin" ), adica joinul unei
tabele cu ea insasi. Pentru a intelege mai bine acest concept vom considera urmatorul exemplu: sa presupunem ca doriti sa aveti ca rezultat o
tabela cu 3 coloane, dar cele trei coloane nu provin in aceeasi tabela din baza de date (empno si deptno apartin tabelei EMP, iar dname tabelei DEPT):

EMPNO DEPTNO DNAME
     

Pentru a ajunge la acest rezultat trebuie sa realizam un join intre cele doua tabele, emp respectiv dept, dupa coloana deptno iar in clauza SELECT
trecem numele celor trei coloane pe care le dorim afisate. Comanda va fi:



Produs cartezian

Putem vorbi de un produs cartezian atunci cand o cinditie a join-ului este omisa sau invalida, atunci cand toate liniile dintr-un tabel sunt adaugate
tuturor liniilor din al doilea tabel. Pentru a evita aparitia unui produs cartezian trebuie sa introducem intotdeauna o conditie valida in clauza WHERE.
De obicei in cazul aparitiei un produs cartezian sunt generate mai multe linii dacat ar fi nevoie, si deci rezulatatul este rar folositor. Totusi exista si
situatii cand este folositoare obtinerea unui astfel de rezultat, de exemplu cand se doreste generarea unui numar mare de linii pentru a simula o
> cantitate mare de date. De exemplu, daca in cazul anterior am obtinut o tabela cu 3 coloane si 14 randuri, daca am fi omis conditia din clauza WHERE:


am obtine o tabela cu 3 coloane si 70 de randuri.


Tipuri de join-uri

Oracle 8i SQL:1999
  • echijoin
  • non-echijoin
  • joinexterior
  • autojoin
  • join incrucisat
  • join natural
  • join cu clauza
  • join exterior lateral (stanga sau dreapta) sau complet
  • conditii arbitrare ptr join-uri externe

Versiunea 9i de la Oracle ofera o sintaxa de join care este in concordanta cu SQL:1999.
Noua sintaxa de join SQL:1999 ofera aceleasi performante ca si versiunile precedente lui Oracle 9i.


Join-uri de tabele folosind sintaxa Oracle

Sintaxa generala:

SELECT tabela1.coloana, tabela2.coloana
FROM tabela1, tabela2
WHERE tabela1.coloana1 = tabela2.coloana2;



talela1.coloana
tabela2.coloana
   reprezinta tabela si coloana de unde se iau informatiile
tabela1.coloana1 = tabela2.coloana2    reprezinta conditia de join, cea care face legatura intre coloane(foreign sau primary kye)

Dupa cum s-a vazut si in exemplele anterioare, numele coloanei este prefixat cu numele tabelei atunci cand acelasi nume de coloana apare in mai
multe tabele, astfel fiind inlaturata ambiguitatea unor nume de coloane.Pentru a se face un join intre n tabele ave, nevoie de minimum (n-1) conditii
de join. Aceasta regula nu se aplica atunci cand intr-o tabela apare o cheie primara concatenata, in acest exemplu fiind nevoie de mai mult de o
coloana pentru o identificare unica a fiecarui rand. In exemplul urmator vom prezenta un join intre cele 3 tabele ale bazei de date:



Echijoin-uri (equijoin)

   -mai sunt numite si join-uri simple sau join-uri interne
   -putem spune ca avem de-a face cu un echijoin atunci cand coloanele implicate in conditia de join sunt egale
   -primul exemplu dat in acest capitol este un exemplu de recuperare a datelor cu echijopin-uri:

In cazul in care se doreste utilizarea de conditii suoplimentare de cautare, se recomanda folosirea operatorului AND:


Aliasuri de tabele

Sintaxa generala :

nume_tabela   alias_tabela

Prin utilizarea aliasurilor de tabele se simplifica interogarile diminuand-use dimensiunea codului si se imbunatatesc performantele. In principiu un alias
poate avea pana la 30 de caractere, dar este indicat sa nu se ajunga la un numar atat de mare. Definirea aliasurilor se face in clauza FROM, dupa cum
vom vedea in exemplul urmator. Atunci cand definim un alias este obligatorie folosirea lui in locul numelui tabelei in clauza SELECT.



Non-echijoin-uri (non-equijoin)

In cazul acestui tip de join in conditia de join nu apare operatorul de egaltate ci alti poperatori (<=; =>; BETWEEN). Pentru a intelege mai bine vom
vom considera urmatorul exemplu care utilizeaza clauza BETWEEN:


Este important de observat ca fiecare angajat apare o singura data atunci cand aceasta cerere este executata. Motivele pentru se intampla acest lucru
sunt:


Join-uri externe (outter join)

Daca realizam un echijoin si exista randuri care nu indeplinesc conditie de join (pentru ca anumite intrari dintr-o tabela nu au corespondenti in cealalta
tabela), atunci acestea nu vor aparea in rezultat. Pentru a putea vizualiza totusi si aceste randuri se foloseste join-ul extern.

Sintaxa generala:

SELECT tabela1.coloana,tabela2.coloana
FROM tabela1, tabela2
WHERE tabela1.coloana (+) = tabela2.coloana;

Operatorul care determina join-ul extern este "+" incadrat inrte doua paranteze (dupa cum se poate vedea si in exemplu); acesta este pozitionat pe partea membrului din conditia de join care are mai putina informatie. In acest mod se creeaza randuri vide la care pot si adaugate radurile din tabela cu mai multa informatie. Exista o anumita restrictrie in cazul folosirii acetui tip de join si anume : o conditie care implica un join extern nu poate folosi operatorul IN sau sa fie legata de o alta conditie prin operatorul OR.

Autojoin-uri (self join)

Exista situatii in care trebuie sa facem legatura dintre o tabela si ea insasi. Sa consideram urmatorul exemplu: sa pesupunem ca am dori sa aflam cine este managerul pentru fiecare angajat. Pentru aceasta trebui sa facem un join intre tabela emp si ea insasi, dupa cum urmeaza:


Dupa cum observati rezultatul contine doar 13 linii desi in tabela avem 14 intrari corespunzatare angajatilor. Acest lucru se intampla deoarece angajatul King nu are nici un superior, si deci nu respecta conditia de join. Pentru ca aceasta intrare sa apara in rezultat trebuie sa folosim un join extern, punanad operatorul "+" in dreapta lui m.empno (coloana cu informatie mai putina) :




Realizarea join-urilor folosind sintaxa SQL:1999


Join incrucisat (cross join)

- echivalent cu produsul cartezian dintre 2 tabeles;

Sintaxa generala :

SELECT tabela1.coloana,tabela2.coloana
FROM tabela1
CROSS JOIN tabela2;

De exemplu :

SELECT ename,dname FROM emp
CROSS JOIN dept;
    <= >     SELECT ename, dname FROM emp, dept;

Join-uri naturale (natural joins)

- echivalent cu un echijoin;

Sintaxa generala :

SELECT tabela1.coloana,tabela2.coloana
FROM tabela1
NATURAL JOIN tabela2;

Acest tip de join, disponibil incepand cu versiunea 9i, se bazeaza pe toate coloanele din cele doua tabele care au acelasi nume (selecteaza randurile din cele 2 tabele care au valori egale in toate coloanele care s-au potrivit). In cazul in care coloanele cu acelasi nume contin tipuri de date diferite este intoarsa o eroare. Daca se doreste impunerea altor restrictii se poate folosi clauza WHERE.

Crearea de join-uri utilizand clauza USING

In momentul in care exista mai multe coloane nu acelasi nume, dar care au tipuri de date diferite, aceasta clauza poate specifica ce coloane vor participa la join. Nu se folosesc nume de tabele sau aliasuri in referirea coloanelor, iar aceasta clauza exclude utilizarea join-ului natural.

Sintaxa generala :

SELECT tabela1.coloana,tabela2.coloana
FROM tabela1
JOIN tabela2 USING (nume_coloana);

Incazul in care se folosesc clauze care limiteaza cautarile (WHERE de exemplu) este generata o eroare.

Crearea de join-uri utilizand clauza ON

Clauza ON este folosita pentru a specifica conditii arbitrare sau coloanele care participa la join. Conditia de join este separata de celelalte conditii de cautare.

Sintaxa generala:

SELECT tabela1.coloana,tabela2.coloana
FROM tabela1 JOIN tabela2
ON (tabela1.nume_coloana1 = tabela2.nume_coloana2);

Aceasta clauza poate fi folosita si pentru realizarea join-ului mai multor tabele:

SELECT tabela1.coloana,tabela2.coloana,tabela3.coloana
FROM tabela1
JOIN tabela2
ON (tabela1.nume_coloana1 = tabela2.nume_coloana2)
............
JOIN tabelan
ON (tabela1.nume_coloana2 = tabelan.nume_coloanam);

In SQL:1999, join-ul dintre 2 tabele care intoarce doar randurile identice se numeste join intern.Daca rezultatul cererii contine si randurile diferite din tabela din stanga (dreapta) conditie de join, atunci join-ul se numeste extern la stanga (dreapta). In cazul in care rezultatul contine atat valorile diferite din stanga cat si pe cele din dreapa, join-ul se numeste conmplet Sintaxa pentru aceste tipuri este:

join extern la stanga join extern la dreapta join extern complet
SELECT t1.coloana,t2.coloana
FROM tabela1 t1
LEFT OUTER JOIN tabela2
ON (t1.nume_coloana1 = t2.nume_coloana2);
SELECT t1.coloana,t2.coloana
FROM tabela1 t1
RIGHT OUTER JOIN tabela2 t2
ON (t1.nume_coloana1 = t2.nume_coloana2);
SELECT t1.coloana,t2.coloana
FROM tabela1 t1
FULL OUTER JOIN tabela2 t2
ON (t1.nume_coloana1 = t2.nume_coloana2);


Exercitii :

1. Scrieti o cerere care sa intoarca numele, numarul si numele departamentului pentru toti angajatii.


2. Scrieti o cerere care sa aiba ca rezultat toate slujbele care se gasesc in departamentul 20. Includeti si locatia departamentului in rezultatul.


3. Realizati o cerere care sa intoarca numele angajatului, numele departamentului, locatia si slujba tuturor celor care castiga un comision.


4. Scrieti o cerere care sa intoarca numele, numarul si numele departamentului si job-ul tuturor celor care lucreaza in Chicago.


Pentru a vizualliza raspunsurile le intrebarile de mai sus, apasati aici: RASPUNSURI



Capitolul precedent Acasa Capitolul urmator