|
Atunci cand in clauza FROM a unei comenzi SELECT apar mai multe tabele se realizeaza produsul cartezian al acestora. De aceea numarul de linii rezultat creste considerabil, fiind necesara restrictionarea acestora cu o clauza WHERE.
Atunci cand este necesara obtinerea de informatii din mai multe tabele se utilizeaza conditii de asociere (join). In acest fel liniile dintr-un tabel pot fi puse in legatura cu cele din alt tabel conform valorilor comune ale unor coloane sau expresii obtinute pe baza coloanelor. Conditiile de corelare utilizeaza de obicei coloanele cheie primara si cheie externa.
Interogarea datelor din mai multe relatii folosind tipuri de asocieri
In SQL putem crea asocieri intre
tabele atat in clauza WHERE cat si in clauza FROM a unei interogari.
Asocierile in clauza FROM au fost introduse in varianta SQL 92 a standardului
Sintaxa uzuala, pentru folosirea asocierilor in clauza WHERE (in stilul ANSI SQL 89) este urmatoarea:
SELECT lista_de_coloane
FROM tabel1, tabel2
WHERE tabel1.coloana1=tabel2.coloana2;
Sintaxa uzuala pentru
folosirea asocierilor in clauza FROM (in stilul
SELECT lista_de_coloane
FROM tabel1 INNER | LEFT [OUTER] | RIGHT [OUTER] |
OUTER este optional.
Pentru asocieri multiple sintaxa clauzei FROM este
FROM tabel1 JOIN tabel2 ON conditia1 JOIN tabel3 ON conditia2 JOIN.
Tipurile de asocieri utilizate in interogarea datelor din mai multe tabele sunt:
INNER JOIN (asociere interna)
LEFT OUTER JOIN (asociere externa la stanga)
RIGHT OUTER JOIN (asociere externa la dreapta)
FULL OUTER JOIN (asociere externa si la stanga si la dreapta)
Inner join asociere interna) - rezultatul asocierii include numai acele randuri din ambele tabele care au valori egale ale cheii de legatura.
SELECT FROM tabel_A INNER JOIN tabel_B (conditii de join)
selecteaza randurile din relatiile A si B care corespund conditiilor de asociere.
Outer join asociere externa) - este vazut ca opusul lui Inner join. Se includ linii dintr-o tabela chiar daca nu exista corespondent in cealalta tabela. Poate fi de tip:
a) left join (asociere la stanga)
Sintaxa
SELECT FROM tabel_A LEFT OUTER JOIN tabel_B ON (conditii de join)
selecteaza toate randurile din A, pe care le completeaza cu informatii din B, in masura in care satisfac conditiile de join; acolo unde nu vor exista informatii din B, acestea vor fi completate cu NULL.
b) right join (asociere la dreapta)
Sintaxa
SELECT FROM tabel_A RIGHT OUTER JOIN tabel_B ON (conditii de join)
selecteaza toate rindurile din B, pe care le completeaza cu informatii din A, in masura in care satisfac conditiile de join; acolo unde nu vor exista informatii din A, acestea vor fi completate cu NULL.
c) full join
Sintaxa
SELECT FROM tabel_A FULL OUTER JOIN tabel_B ON (conditii de join)
Este un INNER JOIN completat cu toate randurile din A care nu au corespondent in B si toate randurile din B care nu au corespondent in A. Acolo unde nu vor exista informatii, acestea vor fi completate cu NULL.
Auto-asocieri
Sunt utile atunci cand avem de-a face cu o asociere recursiva (intre o tabela si ea insasi)
SELECT lista_de_coloane FROM tabel1 as A INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] tabel1 as B ON A.coloana1=B.coloana2;
create table tDonatori
( CodDonator char(10) primary key,
nume char(30) not null
CodDonator nume
d1 Popescu
d2 Andreescu
d3 Radulescu
d4 Ionescu
d5 Georgescu
create table tBeneficiari
( CodBenef char(10) primary key,
nume char(30) not null
CodBenef nume
b1 Ionut
b2 Andreea
b3 Danut
b4 Irina
b5 Marius
create table tDonatii
( idDonatie int identity,
CodDonator char(10) null foreign key references tDonatori(CodDonator),
CodBenef char(10)null foreign key references tBeneficiari(CodBenef),
Suma int
idDonatie CodDonator CodBenef Suma
1 d2 b1 5000
2 d1 b2 200
3 d1 b1 400
4 d3 b2 500
5 NULL b2 1000
6 NULL b1 600
7 NULL NULL 800
8 NULL NULL 400
select nume suma
from tDonatori as A inner join tDonatii as B
on A CodDonator B CodDonator
nume suma
Andreescu 5000
Popescu200
Popescu400
Radulescu 500
select nume suma
from tDonatori as A left join tDonatii as B
on A CodDonator B CodDonator
nume suma
Popescu 200
Popescu 400
Andreescu 5000
Radulescu 500
Ionescu NULL
Georgescu NULL
(6 row(s) affected)
select nume suma
from tDonatori as A right outer join tDonatii as B
on A CodDonator B CodDonator
nume suma
Andreescu 5000
Popescu 200
Popescu 400
Radulescu 500
NULL 1000
NULL 600
NULL 800
NULL 400
(8 row(s) affected)
select nume suma
from tDonatori as A full outer join tDonatii as B
on A CodDonator B CodDonator
nume suma
NULL 1000
NULL 600
NULL 800
NULL 400
Popescu 200
Popescu 400
Andreescu 5000
Radulescu 500
Ionescu NULL
Georgescu NULL
(10 row(s) affected)
select A nume as Donator C nume as Beneficiar suma
from tDonatori as A inner join tDonatii as B
on A CodDonator B CodDonator
inner join tBeneficiari as C on
B CodBenef C CodBenef
Donator Beneficiar suma
Andreescu Ionut 5000
Popescu Andreea 200
Popescu Ionut 400
Radulescu Andreea 500
select A nume as Donator C nume as Beneficiar suma
from tDonatori as A left join tDonatii as B
on A CodDonator B CodDonator
left join tBeneficiari as C on
B CodBenef C CodBenef
Donator Beneficiar suma
Popescu Andreea 200
Popescu Ionut 400
Andreescu Ionut 5000
Radulescu Andreea 500
Ionescu NULL NULL
Georgescu NULL NULL
select A nume as Donator C nume as Beneficiar suma
from tDonatori as A left join tDonatii as B
on A CodDonator B CodDonator
right join tBeneficiari as C on
B CodBenef C CodBenef
DonatorBeneficiarsuma
Andreescu Ionut5000
PopescuIonut400
PopescuAndreea 200
Radulescu Andreea 500
NULL DanutNULL
NULL IrinaNULL
NULL Marius NULL
select A nume as Donator C nume as Beneficiar suma
from tDonatori as A left join tDonatii as B
on A CodDonator B CodDonator
full join tBeneficiari as C
on B CodBenef C CodBenef
Donator Beneficiarsuma
Popescu Andreea 200
Popescu Ionut400
AndreescuIonut5000
RadulescuAndreea 500
Ionescu NULL NULL
GeorgescuNULL NULL
NULLDanutNULL
NULLIrinaNULL
NULLMarius NULL
select A nume as Donator C nume as Beneficiar suma
from tDonatori as A full join tDonatii as B
on A CodDonator B CodDonator
full join tBeneficiari as C on
B CodBenef C CodBenef
Donator Beneficiar suma
AndreescuIonut 5000
Popescu Andreea200
Popescu Ionut 400
RadulescuAndreea500
NULLAndreea1000
NULLIonut 600
NULLNULL 800
NULLNULL 400
GeorgescuNULL NULL
Ionescu NULL NULL
NULLDanut NULL
NULLIrina NULL
NULLMarius NULL
(13 row(s) affected)
select A nume C nume as donator B suma
from
tBeneficiari as A inner join tDonatii as B
on A codBenef B CodBenef and A nume 'andreea'
left join tDonatori as C on B codDonator C CodDonator
sau
select A nume C nume as donator B suma
from
tBeneficiari as A inner join tDonatii as B
on A codBenef B CodBenef
left join tDonatori as C on B codDonator C CodDonator
where A nume 'andreea'
nume donator suma
Andreea Popescu 200
Andreea Radulescu 500
Andreea NULL 1000
(3 row(s) affected)
select A nume sum suma as Total
from
tBeneficiari as A inner join tDonatii as B
on A codBenef B CodBenef and A nume 'andreea' group by A nume
nume Total
Andreea 1700