Top Banner

of 27

Curs 7 Dql Join

Jul 22, 2015

Download

Documents

Mihai Prajescu
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript

Cereri multi relaieComanda SELECT ofer posibilitatea de a consulta informaii care provin din mai multe tabele. Operatorii care intervin n astfel de cereri pot fi: operatori pe mulimi (UNION, UNION ALL, INTERSECT, MINUS); operatori compunere care implementeaz diferite tipuri de JOIN. Exist dou moduri de realizare a cererilor multi-relaie: forma relaional, n care drumul de acces la informaie este n sarcina sistemului. forma procedural, n care trebuie indicat drumul de acces la informaie prin imbricarea de comenzi SELECT; Exemplu: S se obin, utiliznd aceste dou forme, codurile i titlurile crilor mprumutate. a) Forma relaional: SELECT carte.codel, titlu FROM carte, imprumuta WHERE carte.codel = imprumuta.codel; b) Forma procedural (imbricare de comenzi SELECT-Subcereri): SELECT codel, titlu FROM carte WHERE codel IN (SELECT DISTINCT codel FROM imprumuta);

Operatori pe mulimi sau Operatori pentru interogricompuse (UNION, UNION ALL, INTERSECT, MINUS)Uneori este util s se ruleze interogri multiple i s se combine rezultatele ntr-un singur set de rezultate. Operatorii pe mulimi combin rezultatele obinute din dou sau mai multe interogri. Cererile care conin operatori pe mulimi se numesc cereri compuse. Exist patru operatori pe mulimi: UNION, UNION ALL, INTERSECT i MINUS(n unele implementeri oracle operatorul MINUS se numete EXCEPT). Toi operatorii pe mulimi au aceeai preceden. Dac o instruciune SQL conine mai muli operatori pe mulimi, server-ul Oracle evalueaz cererea de la stnga la dreapta (sau de sus n jos). Pentru a schimba aceast ordine de evaluare, se pot utiliza paranteze.1

n mod implicit, pentru toi operatorii cu excepia lui UNION ALL, rezultatul este ordonat cresctor dup valorile primei coloane din clauza SELECT. Pentru o cerere care utilizeaz operatori pe mulimi, cu excepia lui UNION ALL, server-ul Oracle elimin liniile duplicat. n instruciunile SELECT asupra crora se aplic operatori pe mulimi, coloanele selectate trebuie s corespund ca numr i tip de date. Nu este necesar ca numele coloanelor s fie identice. Numele coloanelor din rezultat sunt determinate de numele care apar n clauza SELECT a primei cereri. n cazul n care cererile componente selecteaz date de tip caracter, tipul de date al valorii returnate poate fi CHAR, dac valorile selectate de ambele cereri sunt de tip CHAR, sau VARCHAR2, dac valorile selectate de cel puin una din cele dou cereri sunt de tip VARCHAR2. Observaii: Comenzile SELECT, care intervin n cereri ce conin operatori pe mulimi, trebuie s satisfac anumite condiii: toate comenzile SELECT trebuie s aib acelai numr de coloane; opiunea DISTINCT este implicit (excepie UNION ALL); numele coloanelor sunt cele din prima comand SELECT; dimensiunea coloanei implicit este cea mai mare dintre cele dou coloane; sunt admise combinaii de forma: 1. SELECT1 UNION SELECT2 INTERSECT SELECT3 i ordinea de execuie este de la stnga la dreapta; 2. SELECT1 UNION (SELECT2 INTERSECT SELECT3) i ordinea este dat de paranteze. UNION Operatorul UNION adaug rndurile din setul de nregistrri al unei interogri la cel al unei alte interogri i, n acelai timp, elimin rndurile duplicate, ntr-un mod similar cu cel al cuvntului cheie DISTINCT. Operatorul UNION returneaz deci toate liniile selectate de dou cereri, eliminnd duplicatele. Operaia este permis numai dac interogrile sunt compatibile din punctul de vedere al uniunii, ceea ce nseamn c au acelai numr de coloane i c tipurile de date ale coloanelor corespondente sunt compatibile. Acest operator nu ignor valorile null i are preceden mai mic dect operatorul IN.

2

Exemplu: S se afieze pe o singur coloan toate valorile nenule pentru taxa de inchiriere i taxa de ntrziere din tabelul FILM_NCHIRIAT. SELECT taxa_inchiriat AS TAXA FROM FILM_INCHIRIAT WHERE taxa_inchiriat IS NOT NULL UNION SELECT taxa_intarziere AS TAXA FROM FILM_INCHIRIAT WHERE taxa_intarziere IS NOT NULL; Exemplu: S se afieze codurile operelor de art pentru care a fost ncheiat o poli de asigurare sau care beneficiaz de un sistem de securitate. Fiecare cod va fi afiat o singur dat. SELECT FROM UNION SELECT FROM cod_opera polita_asig cod_opera securitate;

Uneori, pentru a respecta regula conform creia expresiile din clauzele SELECT trebuie s concorde ca numr i tip de date, se pot utiliza coloane artificiale i funcii de conversie pentru tipurile de date. Exemplu: S se listeze codul operelor de art, codul i numele artitilor. SELECT FROM UNION SELECT FROM cod_opera, cod_artist, TO_CHAR(null) nume opera TO_NUMBER(null), cod_artist, nume artist;

Exemplu s se listeze codul salariailor, codul i numele departamentelor.

3

SELECT FROM UNION SELECT FROM

employee_id, department_id, TO_CHAR(NULL) nume employees TO_NUMBER(NULL), department_id, department_name departments;

Daca se utilizeaza UNION ALL obtinem suma celor doua cereri. UNION ALL Operatorul UNION ALL funcioneaz la fel ca i operatorul UNION, exceptnd faptul c rndurile duplicate nu sunt eliminate. Precizrile fcute asupra operatorului UNION sunt valabile i n cazul operatorului UNION ALL. n cererile asupra crora se aplic UNION ALL nu poate fi utilizat cuvntul cheie DISTINCT. Exemplu: S se determine codul operelor de art pentru care s-a ncheiat o poli de asigurare sau pentru care s-a achiziionat un sistem de securitate. S se afieze firma i data contractrii, respectiv a instalrii sistemului. ntruct o oper poate avea mai multe polie de asigurare sau mai multe sisteme de securitate ncheiate, respectiv instalate la aceeai firm i dat, nu se vor suprima liniile duplicat. Rezultatul va fi ordonat dup codul operelor. SELECT cod_opera, firma, semnat_contract FROM polita_asig UNION ALL SELECT cod_opera, firma, data_inst FROM polita_asig ORDER BY cod_opera; Clauza ORDER BY poate aprea numai o singur dat ntr-o cerere compus. Dac se utilizeaz, clauza trebuie plasat la sfritul cererii i accept nume de coloane, alias-uri sau notaia poziional. Numele de coloane i alias-urile din clauza ORDER BY trebuie s fie din lista SELECT a primei instruciuni.

4

INTERSECT Operatorul INTERSECT gsete valorile selectate dintr-o interogare, care apar i ntr-o alt interogare. n esen, gsete intersecia valorilor din cele dou interogri. Acest operator nu ignor valorile null. Totui, doar un numr mic de sisteme DBMS (cele mai importance fiind Oracle i DB2) implementeaz acest operator. Nu exista in Microsoft SQL Server sau MySQL. Exemplu: Exist n tabelul FILM filme pentru care preul pentru DVD este egal cu preul pentru VHS? SELECT pret_DVD AS TAXA FROM FILM WHERE pret_DVD IS NOT NULL INTERSECT SELECT pret_VHS AS TAXA FROM FILM WHERE pret_VHS IS NOT NULL; Exemplu: S se afieze codul operelor de art, respectiv data la care s-a ncheiat o poli de asigurare i s-a instalat un sistem de securitate. SELECT cod_opera, semnat_contract FROM polita_asig INTERSECT SELECT cod_opera, data_inst FROM securitate; Exemplu: S se obin, utiliznd operatorul INTERSECT, codurile crilor din care sunt mai puin de 15 exemplare i care au fost mprumutate de cel puin trei ori. SELECT codel FROM carte WHERE nrex < 15 INTERSECT5

SELECT codel FROM imprumuta GROUP BY codel HAVING COUNT(*) > 3; Exemplu S se obin, folosind operatorul INTERSECT, angajaii care au salariul < 5000 i al cror nume conine litera l pe poziia 3. SELECT employee_id, last_name FROM employees WHERE salary y.pret y.titlu = Baze de date y.autor = POPA;14

Realizarea uniunilor folosind clauza JOINClauza JOIN este scris ca o referin de tabel din clauza FROM i combin lista de tabele din clauza FROM i condiia de legtur scris anterior n clauza WHERE ntr-o singur clauz. Sintaxa general a clauzei JOIN pentru o uniune intern, urmat de cteva exemple. Sintaxa corespunztoare standardului SQL3 este urmtoarea: SELECT tabel_1.nume_coloan, tabel_2.nume_coloan FROM tabel_1 [CROSS JOIN tabel_2] | [NATURAL JOIN tabel_2] | [JOIN tabel_2 USING (nume_coloan) ] | [JOIN tabel_2 ON (tabel_1.nume_coloan = tabel_2.nume_coloan) ] | [LEFT | RIGHT | FULL OUTER JOIN tabel_2 ON (tabel_1.nume_coloan = tabel_2.nume_coloan) ];

Clauza ON permite specificarea unei condiii similare cu cea din clauza WHERE . Clauza USING specific numele coloanelor folosite pentru legarea rndurilor. Totui, clauza USING acioneaz numai atunci cnd coloanele pe care se face legtur au nume identice n ambele tabele. JOIN tabel_2 USING nume_coloan efectueaz un equijoin pe baza coloanei cu numele specificat n sintax. Aceast clauz este util dac exist coloane avnd acelai nume, dar tipuri de date diferite. Coloanele referite n clauza USING trebuie s nu conin calificatori (s nu fie precedate de nume de tabele sau alias-uri) n nici o apariie a lor n instruciunea SQL. Clauzele NATURAL JOIN i USING nu pot coexista n aceeai instruciune SQL. JOIN tabel_2 ON tabel_1.nume_coloan = tabel_2.nume_coloan efectueaz un equijoin pe baza condiiei exprimate n clauza ON. Aceast clauz permite specificarea separat a condiiilor de join, respectiv a celor de cutare sau filtrare (din clauza WHERE).

15

Exemple: JOIN cu condiie ON: SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM JOIN FILM_GEN ON FILM.FILM_GEN_COD = FILM_GEN.FILM_GEN_COD ORDER BY FILM_ID; JOIN cu pseudonime n loc de nume de tabele: SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM A JOIN FILM_GEN B ON A.FILM_GEN_COD = B.FILM_GEN_COD ORDER BY FILM_ID; JOIN folosind cuvntul cheie USING (n locul condiiei ON) o scurtatur elegant atunci cnd coloanele din cele dou tabele au acelai nume (nu e recunoscut de toate SGBD-urile). SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM JOIN FILM_GEN USING (FILM_GEN_COD) ORDER BY FILM_ID; JOIN cu cheie extern pe mai multe coloane. Aceast interogare afieaz lista cu copiile filmelor din tabelul FILM_COPY care nu au fost vndute (coloan DATA_VANZARE conine o valoare nul dac nu a fost vndut) i care au fost nchiriate (uniune cu tabelul FILM_INCHIRIAT) dar nu au fost nc returnate (coloan RETUR_DATA conine o valoare nul pn la returnarea filmului). SELECT FILM_ID, COPY_NUMAR, DATA_RETURNARII FROM FILM_COPY JOIN FILM__INCHIRIAT USING (FILM_ID, COPY_NUMAR) WHERE DATA_VANZARE IS NULL AND RETUR_DATA IS NULL; FILM _ID 2 3 COPY_NUMAR 2 2 DATA_RETURNARII 02/27/2009 03/04/200916

5 5 10 17

1 2 1 1

02/27/2009 02/19/2009 03/04/2009 03/04/2009

Instruciunile care folosesc clauza JOIN sunt mai scurte. Interogarea precedent scris folosind condiii de legtur n clauza WHERE. Se remarc faptul c n acest caz trebuie specificat numele complet al coloanelor FILM_ID i COPY_NUMAR, pentru a evita referirea ambigu a lor. Instruciunea de mai jos afieaz aceleai rezultate ca i instruciunea anterioar. SELECT A.FILM_ID, A.COPY_NUMAR, DATA_RETURNARII FROM FILM_COPY A, FILM_INCH B WHERE A.FILM_ID = B.FILM_ID AND A.COPY_NUMAR = B.COPY_NUMAR AND DATA_VANZARE IS NULL AND RETURN_DATA IS NULL; Uniuni naturale O uniune natural (natural join) se bazeaz pe toate coloanele cu acelai nume din dou tabele, n esen, toate uniunile de egalitate sunt uniuni naturale. Totui, sintaxa unei uniuni naturale este mult mai simpl, deoarece nu este necesar s specificai o condiie sau o list de coloane - se nelege de la sine care sunt coloanele folosite. Nu toate SGBD-urile accept aceast sintax pentru clauza JOIN (accepta sigur Oracle i MySQL ). Exemplu: uniunea tabelelor FILM i FILM_GEN, rescris sub forma unei uniuni naturale: SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM NATURAL JOIN FILM_GEN ORDER BY FILM_ID; Uniunile pot implica mai mult de dou tabele. Exemplul urmtor prezint o uniune natural care obine coloana FILM_ID din tabelul FILM, coloana FILM_GEN_DESCRIERE din tabelul FILM_GEN i din tabelul MPAA_RATING, coloana MPAA_RATING_DESCRIERE , pentru primele trei

17

filme din tabelul FILM. Folosirea clauzei WHERE permte s se elimine din setul de rezultate rndurile de care nu avem nevoie. Exemplul folosete dou clauze JOIN. Prima clauz JOIN cere motorului SQL s lege tabelele FILM i FILM_GEN, iar a dou clauz JOIN i cere s lege rndurile deja unite (n esen, un set de rezultate intermediar) cu tabelul MPAA_RATING. SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, MPAA_RATING_COD AS RATING, MPAA_RATING_DESCRIERE AS RATING_DESC FROM FILM NATURAL JOIN FILM_GEN NATURAL JOIN MPAA_RATING WHERE FILM_ID < 4 ORDER BY FILM_ID;

FILM_ID

GEN

RATING

RATING_DESC

1 2 3

Drama

R

Sub 17 ani acompaniati de parinti Sub 17 ani acompaniati de parinti Cu acordul strict a parintilor

Aciune si Aventura R

Comedie

PG-13

Dac se folosete o implementare SQL care nu accept uniunile naturale, aceeai interogare scris folosind cuvintele cheie JOIN i ON este: SELECT A.FILM_ID, B.FILM_GEN_DESCRIERE AS GEN, C.MPAA_RATING__COD AS RATING, C.MPAA_RATING__DESCRIERE AS RATING_DESC FROM FILM A JOIN FILM_GEN B ON A.FILM_GEN_COD = B.FILM_GEN_COD JOIN MPAA_RATING C ON A.MPAA_RATING_COD = C.MPAA_RATING_COD WHERE FILM_ID < 4 ORDER BY FILM_ID; Exemple la schema galerii de arta a) S se determine titlul operelor de art expuse n galeriile avnd codul 10 sau 30, respectiv numele i prenumele artitilor care le-au realizat.18

SELECT FROM WHERE

titlu, nume, prenume opera NATURAL JOIN artist cod_galerie IN (10, 30);

Folosind clauza USING, acest exemplu poate fi rescris astfel: SELECT titlu, nume, prenume FROM opera JOIN artist USING (cod_artist) WHERE cod_galerie IN (10, 30); Urmtoarea cerere va returna eroarea ORA-25154: column part of USING clause cannot have qualifier, ntruct coloana specificat n clauza USING apare, n clauza WHERE, precedat de un alias de tabel. SELECT o.titlu, a.nume, a.prenume FROM opera o JOIN artist a USING (cod_artist) WHERE a.cod_artist IN (50,60); b) S se afieze titlurile operelor de art, firmele la care sunt asigurate i descrierea polielor de asigurare corespunztoare. SELECT o.titlu, p.firma, p.descriere FROM opera o JOIN polita_asig p ON (o.cod_opera = p.cod_opera);

Uniuni externe (outer joins)Toate uniunile pe care le-am descris pn acum sunt uniuni exclusiv (uniuni interne), ceea ce nseamn c singurele rnduri care apar n setul de rezultate sunt cele pentru care a fost gsit o legtur n toate tabelele unite. Exist situaii n care se dorete s includei n rezultatele interogrii i rnduri pentru care nu exist o legtur. De exemplu, dac se dorete o list cu toate genurile de filme, mpreun cu toate titlurile asociate cu fiecare gen? O uniune extern (outer join) - pentru care un nume mai potrivit ar fi uniune inclusiv - include n setul de rezultate i rndurile pentru care nu exist legturi din cel puin unul dintre tabele. Atunci cnd exist rnduri fr legturi, datele selectate din tabelul n care nu a fost gsit o legtur primesc valoarea nul.19

Un outer join esye utilizat in doua moduri : Cu Operatorul (+) Cu outer join left|right|full OUTER JOIN Operatorul (+) Un outer join este utilizat pentru a obine n rezultat i nregistrrile care nu satisfac condiia de join. Operatorul pentru outer join este semnul plus inclus ntre paranteze (+), care se plaseaz n acea parte a condiiei de join care este deficient n informaie. Efectul acestui operator este de a uni liniile tabelului care nu este deficient n informaie i crora nu le corespunde nici o linie n cellalt tabel cu o linie cu valori null. Operatorul (+) poate fi plasat n orice parte a condiiei de join, dar nu n ambele pri. O condiie care presupune un outer join nu poate utiliza operatorul IN i nu poate fi legat de alt condiie prin operatorul OR. Exemplu: Se presupune c tabelul artist conine i artiti care nu au opere expuse n muzeu. S se afieze artitii i operele acestora, inclusiv cei care nu au opere corespunztoare n tabelul opera. SELECT a.cod_artist, nume, prenume, cod_opera, titlu FROM artist a, opera o WHERE a.cod_artist = o.cod_artist (+); Uniune extern cu outer join Sintaxa general pentru o uniune extern este: nume_tabel {RIGHT | LEFT | FULL} [OUTER] JOIN nume_tabel { ON condiie | USING (nume_coloan [ ,nume_coIoan. ..]) } Exist trei tipuri de baz: Uniune extern ctre stnga (left outer join). Returneaz toate rndurile din tabelul din stnga (cel specificat primul n clauza JOIN), mpreun cu toate rndurile din tabelul din dreapta pentru care poate fi gsit o legtur. (asemnatoare interogrilor din tabele aflate in relaia 1:m) Uniune extern ctre dreapta (right outer join). Returneaz toate rndurile din tabelul din dreapta (cel specificat al doilea n clauza JOIN), mpreun cu toate rndurile din tabelul din stnga pentru care poate fi gsit o legtur, n esen, o uniune extern ctre stnga poale fi rescris ca o uniune extern ctre dreapta20

inversnd ordinea de specificare a tabelelor i nlocuind cuvntul cheie LEFT cu RIGHT. Uniune extern complet (full outer join). Returneaz toate rndurile din ambele tabele. Acest tip de uniune este cel mai puin probabil s fie acceptat de toate implementari;e SQL. Aceast uniune nu este acelai lucru cu un produs cartezian, care leag fiecare rnd dintr-un tabel cu fiecare rnd din cellalt tabel. O uniune extern complet leag fiecare rnd dintr-un tabel cu zero sau mai multe rnduri corespondente din cellalt tabel. Este folosit mai mult pentru tabelele aflate in relaia m:m Exemple de uniuni externe: S se afieze toate descrierile genurilor de filme, mpreun cu filmele asociate fiecrui gen. n setul de rezultate rndurile care nu au nici o valoare n coloan FILM_TITLU - acestea sunt genurile de filme care nu au filme asociate. Dac implementarea DBMS nu accept uniuni realizate cu cuvntul cheie USING, modificai instruciunea astfel nct s utilizeze cuvntul cheie ON, ca n exemplul care urmeaz dup acesta. SELECT FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM_GEN LEFT OUTER JOIN FILM (FILM_GEN_COD); GEN Actiune i Aventura Actiune i Aventura Actiune i Aventura Actiune i Aventura Actiune i Aventura Actiune i Aventura Actiune i Aventura Anime and Animation Copii i Familie FILM_TITLU Kill Bill: Vol. 1 Man on Fire Pirates of the Caribbean Master and Commander The Day After Tomorrow The Last Samurai The Italian Job

USING

21

Clasic Comedie Comedie Comedie Comedie Documentar Drama Drama Drama Drama Drama Drama Strain Horror Independent Musical Romantic Romantic

50 First Dates Matchstick Men The School of Rock Something's Gotta Give Big Fiah Road to Perdition Mystic River Monster Cold Mountain Lost n Translation Das Boot

13 Going on 30 Two Weeks Notice

Interogarea anterioar, rescris ca uniune extern ctre dreapta, cu condiie ON.

SELECT FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM RIGHT OUTER JOIN FILM_GEN ON FILM.FILM_GEN_COD =FILM_GEN.FILM_GEN_COD; Interogarea anterioar, rescris ca uniune extern complet. Deoarece fiecare film trebuie s aib asociat un gen, aceast interogare va produce aceleai rezultate ca i uniunea extern ctre dreapta din interogarea anterioar. Totui, dac genurile filmelor ar fi opionale, uniunea extern complet v-ar fi permis s afiai att genurile care nu au filme asociate, ct i filmele care nu au genuri asociate. SELECT FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM FULL OUTER JOIN FILM_GEN ON FILM.FILM_GEN_COD = FILM_GEN.FILM_GEN_COD;

22

Afiai descrierile genurilor care nu au nume asociate. Exist i alte moduri de a face acest lucru, dar exemplul de fa folosete faptul c rndurile pentru care nu exist legturi returneaz valori nule pentru a selecta numai genurile care nu au nume asociate. SELECT FILM_GEN_DESCRIERE AS GEN FROM FILM RIGHT OUTER JOIN FILM_GEN ON FILM.FILM_GEN_COD = FILM_GEN.FILM_GEN_COD WHERE FILM_TITLU IS NULL; GEN Animatie Copii i Familie Clasic Documentar Horror Independent Musical SF Special Interes Sport Thriller Ca rspuns la cererile clienilor, mai muli productori de baze de date relaionale au introdus uniunile externe inainte de standardizarea clauzei JOIN. Seciunile urmtoare prezint cteva implementri specifice ale sintaxei uniunii externe. Aceste soluii particulare sunt prezentate aici numai pentru c s-ar putea s le intlnii n instruciuni SQL mai vechi Exemplu: a) S se afieze titlurile operelor de art i firmele la care acestea sunt asigurate. Se vor lua n considerare i operele de art pentru care nu au fost ncheiate polie de asigurare. SELECT titlu, firma FROM opera o LEFT OUTER JOIN polita_asig p ON (o.cod_opera = p.cod_opera);

23

b) S se afieze artitii (nume, prenume) i operele acestora, inclusiv cei care nu au opere expuse n cadrul muzeului. SELECT nume, prenume, titlu FROM opera o RIGHT OUTER JOIN artist a ON (o.cod_artist = a.cod_artist); c) S se afieze numele i prenumele artitilor, precum i titlurile operelor create de acetia. Se vor afia i artitii care nu au opere expuse n cadrul muzeului, precum i titlurile operelor al cror autor este necunoscut. SELECT nume, prenume, titlu FROM opera o FULL OUTER JOIN artist a ON (o.cod_artist = a.cod_artist); S se obin titlurile crilor i numele domeniului cruia i aparin, remarcnd si situaiile n care domeniul nu ar avea cri (dac domeniul este fr cri atunci apare null la titlul crii). SELECT titlu, intdom FROM carte, domeniu WHERE carte.coded(+) = domeniu.coded; Exemplu: Considerm c tabelele dept i emp au urmtorul coninut: dept emp deptno dname empno deptno 1 algebra 101 null 2 analiza 102 null 103 null 105 1 106 1 Interogarea urmtoare furnizeaz lista tuturor salariailor si informatii despre departamentele in care lucreaza, inclusiv a celor care nu sunt asignai nici unui departament (right outher join). SELECT a.deptno, a.dname, b.empno, b.deptno FROM dept a, emp b WHERE a.deptno(+) = b.deptno; Rezultatul cererii anterioare va fi: a.deptno a.dname b.empno b.deptno 101 10224

103 1 algebra 105 1 1 algebra 106 1 Interogarea urmtoare afieaz lista departamentelor, inclusiv a celor care nu au salariai (left outer join). SELECT a deptno, a.dname, b.empno, b.deptno FROM dept a, emp b WHERE a.deptno = b.deptno(+); Rezultatul cererii anterioare va fi: a.deptno a.dname b.empno b.deptno 1 algebra 105 1 1 algebra 106 1 2 analiza null null Interogarea urmtoare produce ca rezultat departamentele, chiar i cele fr funcionari, i funcionarii, chiar i cei care nu sunt asignai nici unui departament (full outer join). SELECT NVL(TO_CHAR(b.empno),***) id, NVL(a.dname,***) nume_dep FROM dept a, emp b WHERE a.deptno = b.deptno(+) UNION SELECT NVL(TO_CHAR(b.empno),***) id, NVL(a.dname,***) nume_dep FROM dept a, emp b WHERE a.deptno(+) = b.deptno; Rezultatul cererii va fi: id nume_dep *** analiza 101 *** 102 *** 103 *** 105 algebra 106 algebra

25

Exemplu utilizand ambele variant de outer join: Comanda corecta care afiseaza numele salariatilor si numele departamentelor in care lucreaza acestia, incluzand in rezultat si salariatii care nu lucreaza in niciun departament este: SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e , departments d WHERE e.DEPARTMENT_ID= d.DEPARTMENT_ID(+); SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e LEFT OUTER JOIN departments d ON (e.DEPARTMENT_ID= d.DEPARTMENT_ID); Utilizand USING in loc de ON (nu trebuie sa mai avem alias-uri) SELECT employee_id,last_name, department_id, department_name FROM employees e LEFT OUTER JOIN departments d USING (DEPARTMENT_ID); 2. Comanda corecta care afiseaza numele salariatilor si numele departamentelor in care lucreaza acestia, incluzand in rezultat si departamentele fara salariati este: SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e , departments d WHERE e.DEPARTMENT_ID(+)= d.DEPARTMENT_ID; SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e RIGHT OUTER JOIN departments d ON (e.DEPARTMENT_ID= d.DEPARTMENT_ID); Utilizand USING in loc de ON (nu trebuie sa mai avem alias-uri) SELECT employee_id,last_name, department_id, department_name FROM employees RIGHT OUTER JOIN departments USING (DEPARTMENT_ID);

26

Comanda corecta care afiseaza numele salariatilor si numele departamentelor in care lucreaza acestia, incluzand in rezultat si salariatii fara departamente si departamentele fara salariati este: SELECT employee_id,last_name, department_id, department_name FROM employees FULL OUTER JOIN departments USING (DEPARTMENT_ID); FULL OUTER JOIN nu poate fi implementat cu operatorul (+), deoarece acesta nu poate fi pus in ampele parti a semnului egal. Se poate folosi operatorul pe multimi UNION. SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e , departments d WHERE e.DEPARTMENT_ID(+)= d.DEPARTMENT_ID UNION SELECT e.employee_id,last_name, e.department_id, department_name FROM employees e LEFT OUTER JOIN departments d ON (e.DEPARTMENT_ID= d.DEPARTMENT_ID); Uniuni ncruciate (cross joins) O uniune ncruciat (cross join) nu este altceva dect sintaxa standard pentru un produs cartezian. Interogarea care unea tabelele FILM i FILM_GEN i obinea un produs cartezian SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM, FILM_GEN ORDER BY FILM_ID; poate fi rescris ca mai jos, folosind o uniune ncruciat: SELECT FILM_ID, FILM_GEN_DESCRIERE AS GEN, FILM_TITLU FROM FILM CROSS JOIN FILM_GEN ORDER BY FILM_ID; Se observa diferenta dintre FULL OUTER JOIN si CROSS JOIN(care este produs cartezian) SELECT employee_id, last_name, department_id, department_name FROM employees CROSS JOIN departments d; ON (e.DEPARTMENT_ID= d.DEPARTMENT_ID);

27