Sunteți pe pagina 1din 11

5.7.

Theta şi echijoncţiunea

Dintre tipurile de joncţiuni prezentate în capitolul 3, vom insista în aceast subcapitol asupra theta –
joncţiunii şi echijoncţiunii. SQL nu prezintă clauze sau operatori speciali pentru joncţiune, însă după cum
am văzut, joncţiunea se constituie ca o combinaţie între produs cartezian şi selecţie.

Exemplu:
Exemplul algebrei relaţionale pentru theta – joncţionarea relaţiilor R1 şi R2 se scrie:

SELECT *
FROM R1, R2
WHERE R1.C1 > R2.C5

iar pentru echijoncţiune:

SELECT *
FROM R1, R2
WHERE R1.C1 = R2.C5

Joncţiunea naturală poate fi realizată numai prin specificarea numelor atributelor în clauza SELECT a
frazei de interogare. În standardul SQL-92 şi în implementările SQL ale multor SGBD-uri se poate folosi
o variantă mai elegantă, ţinând seama şi de faptul că tot ce înseamnă theta- şi echijoncţiune reprezintă
pentru SQL, INNER JOIN (joncţiune internă).
Prin urmare, cele două soluţii de mai sus pot fi rescrise, după cum urmează:

SELECT *
FROM R1 INNER JOIN R2 ON R1.C1 > R2.C5,

respectiv

SELECT *
FROM R1 INNER JOIN R2 ON R1.C1 = R2.C3.

Exemplu:
Să se afle numele, facultatea şi secţia studenţilor care stau la căminul Caminul Sportiv?.

- varianta 1 (generală):

SELECT nume, facultate, sectia,


STUDCAMIN.nume camin
FROM STUDENT, STUDCAMIN
WHERE STUDENT.numar matricol =
STUDCAMIN.numar matricol AND
STUDCAMIN.nume camin = „Caminul Sportiv”

- varianta 2 (Microsoft Access)

SELECT STUDENT.Nume, STUDENT.Facultate, STUDENT.Sectia,


STUDCAMIN.[Nume camin]
FROM STUDENT INNER JOIN STUDCAMIN ON
STUDENT.[Numar matricol] = STUDCAMIN.[Numar matricol]
WHERE (((STUDCAMIN.[Nume camin])="Caminul Sportiv"));

Nume Facultate Sectia Nume camin


Stanciu Andreea Stiinte Juridice DREPT Caminul Sportiv
Buciumeanu Olivia Stiinte Economice CIG Caminul Sportiv

Exemplu:
Care sunt cărţile scrise de Radu Irina?

- varianta 1 (generală):
SELECT titlu, AUTOR.nume autor
FROM AUTOR, AUTORCARTE, CARTE
WHERE AUTOR.cod autor =
AUTORCARTE.cod autor AND
AUTORCARTE.cota carte = CARTE.cota carte
AND nume autor = „Victor Stanciu”

- varianta 2 (Microsoft Access):

SELECT CARTE.Titlu, CARTE.Editura, AUTOR.[Nume autor]


FROM AUTOR INNER JOIN (CARTE INNER JOIN AUTORCARTE
ON CARTE.[Cota carte] = AUTORCARTE.[Cota carte])
ON AUTOR.[Cod autor] = AUTORCARTE.[Cod autor]
WHERE (((AUTOR.[Nume autor])="Radu Irina"));

Titlu Editura Nume autor


Sisteme expert ProUnivesitaria Radu Irina
Drept comercial Nemira Radu Irina
Marketing. De la practica la teorie Bibliotheca Radu Irina

Exemplu:
Numele studenţilor care au împrumutat cărţi din domeniul Informatică.

- varianta 1 (generală):

SELECT nume
FROM CARTE, STUDCARTE, STUDENT
WHERE CARTE.cota carte = STUDCARTE.cota carte AND STUDCARTE.numar
matricol = STUDENT.numar matricol AND domeniu = „Informatica”

- varianta 2 (Microsoft Access):

SELECT STUDENT.Nume, CARTE.Titlu, CARTE.Domeniu


FROM STUDENT INNER JOIN (CARTE INNER JOIN STUDCARTE ON CARTE.[Cota
carte] = STUDCARTE.[Cota carte]) ON STUDENT.[Numar matricol] = STUDCARTE.
[Numar matricol]
WHERE (((CARTE.Domeniu)="Informatica"));

Nume Titlu Domeniu


Iancu Loredana Baze de date Informatica
Iancu Loredana Baze de date Informatica
Bojianu Mirela Baze de date Informatica
Balasa Mihai Informatica Economica Informatica
Tudorache Ionelia Sisteme informatice de gestiune Informatica
Tudorache Ionelia Microfost Office - Word Informatica
Neacsu Florin Baze de date relationale Informatica
Nume Titlu Domeniu
Stanciu Mirela Birotica Informatica
Tudorache Ionelia SQL pentru incepatori Informatica
Zamfir Octavian Baze de date relationale Informatica
Vasilescu Ada SQL pentru incepatori Informatica
Danciu Daria Baze de date Informatica
Danciu Daria Microfost Office - PowerPoint Informatica
Bobeica Lidia Sisteme expert Informatica
Ionescu Octavian Microfost Office - Excel Informatica

Exemplu:
Numele şi secţia studenţilor Facultăţii de Ştiinţe Economice care au împrumutat cartea cu titlul Baze de
date în luna februarie 2017?

- varianta 1 (generală):

SELECT nume, sectia


FROM CARTE, STUDCARTE, STUDENT
WHERE CARTE.cota carte = STUDCARTE.cota carte AND STUDCARTE.numar
matricol = STUDENT.numar matricol AND titlu = „Informatica de gestiune” AND
facultate = „Stiinte Economice” AND data_imprumut BETWEEN „01/02/2004” AND
„29/02/2004”

- varianta 2 (Microsoft Access):

SELECT STUDENT.Nume, STUDENT.Facultate, STUDCARTE.[Data imprumut],


CARTE.Titlu
FROM STUDENT INNER JOIN (CARTE INNER JOIN STUDCARTE ON CARTE.[Cota
carte] = STUDCARTE.[Cota carte]) ON STUDENT.[Numar matricol] = STUDCARTE.
[Numar matricol]
WHERE (((STUDCARTE.[Data imprumut]) Between #3/1/2017# And #3/31/2017#)
AND ((CARTE.Titlu)="Baze de date"));
Nume Facultate Sectia Data imprumut Titlu
Iancu Loredana Stiinte Economice MG 3/1/2017 Baze de date
Iancu Loredana Stiinte Economice MG 3/8/2017 Baze de date
Bojianu Mirela Stiinte Economice FB 3/7/2017 Baze de date
Danciu Daria Stiinte Economice CIG 3/15/2017 Baze de date

Nume Facultate Data imprumut Titlu


Iancu Loredana Stiinte Economice 3/1/2017 Baze de date
Iancu Loredana Stiinte Economice 3/8/2017 Baze de date
Bojianu Mirela Stiinte Economice 3/7/2017 Baze de date
Danciu Daria Stiinte Economice 3/15/2017 Baze de date

Exemplu:
Din ce localităţi sunt studenţii născuţi în anul 1995?

- varianta 1 (generală):

SELECT Nume,Data nasterii,Nume localitate


FROM STUDENT, LOCALITATE
WHERE LOCALITATE.Cod localitate = STUDENT.Cod localitate AND Data nasterii
Between 01/01/1995 And 12/31/1995

- varianta 2 (Microsoft Access):

SELECT STUDENT.Nume, STUDENT.[Data nasterii], LOCALITATE.[Nume


localitate]
FROM LOCALITATE INNER JOIN STUDENT ON LOCALITATE.[Cod localitate] =
STUDENT.[Cod localitate]
WHERE (((STUDENT.[Data nasterii]) Between #1/1/1995# And #12/31/1995#));

Nume Data nasterii Nume localitate


Sitaru Ionut 5/5/1995 Targoviste
Musat Florin 3/23/1995 Moreni
Bobeica Lidia 4/15/1995 Gaesti
Sandu Georgeta 2/9/1995 Pitesti
Butu Ion 8/30/1995 Moreni
Exemplu:
În ce cămin sunt cazaţi studenţii care au bursă de merit şi excepţională?

- varianta Microsoft Access:

SELECT STUDENT.Nume, STUDCAMIN.[Nume camin], BURSA.[Tip bursa]


FROM (STUDENT INNER JOIN BURSA ON STUDENT.[Numar matricol] = BURSA.
[Numar matricol]) INNER JOIN STUDCAMIN ON STUDENT.[Numar matricol] =
STUDCAMIN.[Numar matricol]
WHERE (((BURSA.[Tip bursa])="Merit")) OR (((BURSA.[Tip
bursa])="Exceptionala"));

Nume Nume camin Tip bursa


Balasa Mihai Caminul nr. 2 Merit
Neacsu Florin Caminul nr. 2 Exceptionala
Musat Florin Caminul nr. 1 Exceptionala
Bobeica Lidia Caminul nr. 2 Merit
Sandu Georgeta Caminul nr. 2 Merit

Exemplu:
Cum se numesc studenţii care nu sunt din Târgovişte, au bursă de merit şi sunt cazaţi în Caminul nr. 2?

- varianta Microsoft Access:

SELECT STUDENT.Nume, LOCALITATE.[Nume localitate], BURSA.[Tip bursa],


STUDCAMIN.[Nume camin]
FROM LOCALITATE INNER JOIN ((STUDENT INNER JOIN BURSA ON STUDENT.
[Numar matricol] = BURSA.[Numar matricol]) INNER JOIN STUDCAMIN ON
STUDENT.[Numar matricol] = STUDCAMIN.[Numar matricol]) ON LOCALITATE.
[Cod localitate] = STUDENT.[Cod localitate]
WHERE (((LOCALITATE.[Nume localitate])<>"Targoviste") AND ((BURSA.[Tip
bursa])="Merit") AND ((STUDCAMIN.[Nume camin])="Caminul nr. 2"));

Nume Nume localitate Tip bursa Nume camin


Balasa Mihai Craiova Merit Caminul nr. 2
Bobeica Lidia Gaesti Merit Caminul nr. 2
Sandu Georgeta Pitesti Merit Caminul nr. 2

Exemplu:
Care sunt studenţii Facultăţii de Ştiinţie Economice, născuţi înainte de anul 1992, care au împrumutat
cărţi în anul 2016.

- varianta Microsoft Access:

SELECT DISTINCT STUDENT.Nume, STUDENT.Facultate, STUDENT.[Data


nasterii], STUDCARTE.[Data imprumut]
FROM CARTE INNER JOIN (STUDENT INNER JOIN STUDCARTE ON STUDENT.
[Numar matricol] = STUDCARTE.[Numar matricol]) ON CARTE.[Cota carte] =
STUDCARTE.[Cota carte]
WHERE (((STUDENT.Facultate)="Stiinte Economice") AND ((STUDENT.[Data
nasterii])<#1/1/1992#) AND ((STUDCARTE.[Data imprumut]) Between #1/1/2016#
And #12/31/2016#));
Nume Facultate Data nasterii Data imprumut
Buciumeanu Olivia Stiinte Economice 1/1/1989 3/22/2016
Danciu Daria Stiinte Economice 2/16/1991 3/15/2016
Tudorache Ionelia Stiinte Economice 4/5/1991 3/15/2016
Tudorache Ionelia Stiinte Economice 4/5/1991 3/21/2016
Zamfir Octavian Stiinte Economice 8/23/1986 3/14/2016

Observaţie: Studentul Tudorache Ionelia apare de două ori, pentru că datele de împrumut sunt diferite.

Exemplu:
Din ce localităţi sunt studenţii care au împrumutat cărţile Baze de date şi SQL pentru începători?

- varianta Microsoft Access:

SELECT DISTINCT STUDENT.Nume, LOCALITATE.[Nume localitate], CARTE.Titlu


FROM LOCALITATE INNER JOIN (STUDENT
INNER JOIN (CARTE
INNER JOIN STUDCARTE
ON CARTE.[Cota carte] = STUDCARTE.[Cota carte])
ON STUDENT.[Numar matricol] = STUDCARTE.[Numar matricol])
ON LOCALITATE.[Cod localitate] = STUDENT.[Cod localitate]
WHERE (((CARTE.Titlu)="SQL pentru incepatori" Or (CARTE.Titlu)="Baze de
date"));

Nume Nume localitate Titlu


Bojianu Mirela Gaesti Baze de date
Danciu Daria Targoviste Baze de date
Iancu Loredana Targoviste Baze de date
Tudorache Ionelia Timisoara SQL pentru incepatori
Vasilescu Ada Gaesti SQL pentru incepatori

Exemplu:
Cum se numesc studenţii care au împrumutat cărţi scrise de autori străini?

- varianta Microsoft Access:

SELECT DISTINCT STUDENT.Nume, CARTE.Titlu, AUTOR.[Nume autor],


AUTOR.Nationalitate
FROM AUTOR INNER JOIN ((STUDENT
INNER JOIN (CARTE
INNER JOIN STUDCARTE
ON CARTE.[Cota carte] = STUDCARTE.[Cota carte])
ON STUDENT.[Numar matricol] = STUDCARTE.[Numar matricol]) INNER JOIN
AUTORCARTE
ON CARTE.[Cota carte] = AUTORCARTE.[Cota carte])
ON AUTOR.[Cod autor] = AUTORCARTE.[Cod autor]
WHERE (((AUTOR.Nationalitate)<>"roman"));

Nume Titlu Nume autor Nationalitate


Balasa Mihai Informatica Economica Obrien James Canadian
Buciumeanu Olivia Macroeconomie Maria Loire Francez
Danciu Daria Microfost Office - PowerPoint Delobel Claude Francez
Ionescu Octavian Macroeconomie Maria Loire Francez
Sitaru Ionut Drept penal Elamgarmid Karl Suedez
Tudorache Ionelia Contabilitate generala Kunst Olivia German
Tudorache Ionelia Microfost Office - Word Elamgarmid Karl Suedez
Tudorache Ionelia Sisteme informatice de gestiune Gabay Julien Francez

Exemplu:
În ce an s-au născut autorii ale căror cărţi au for împrumutate de studenţii Facultăţii de Ştiinţe
Economice care au bursă de merit?

- varianta Microsoft Access:

SELECT DISTINCT AUTOR.[Nume autor], AUTOR.[An nastere], STUDENT.Nume,


STUDENT.Facultate, BURSA.[Tip bursa]
FROM (AUTOR INNER JOIN ((STUDENT
INNER JOIN (CARTE
INNER JOIN STUDCARTE
ON CARTE.[Cota carte] = STUDCARTE.[Cota carte])
ON STUDENT.[Numar matricol] = STUDCARTE.[Numar matricol]) INNER JOIN
AUTORCARTE
ON CARTE.[Cota carte] = AUTORCARTE.[Cota carte])
ON AUTOR.[Cod autor] = AUTORCARTE.[Cod autor])
INNER JOIN BURSA
ON STUDENT.[Numar matricol] = BURSA.[Numar matricol]
WHERE (((BURSA.[Tip bursa])="Merit"));

Nume autor An nastere Nume Facultate Tip bursa


Istrate Vasile 1975 Sandu Georgeta Stiinte Juridice Merit
Obrien James 1955 Balasa Mihai Stiinte Economice Merit
Radu Irina 1976 Bobeica Lidia Stiinte Economice Merit

5.8. Subconsultări
Una dintre cele mai importante facilităţi oferite de SQL constă în includerea unei consultări în alta,
pe două sau mai multe niveluri – cu alte cuvinte, utilizarea subconsultărilor. Prin aceste subconsultări se
obţin tabele temporare intermediare ce vor fi folosite drept „argumente” în frazele SELECT superioare.
În materie de subconsultări, cel mai utilizat operator este IN, pe care deja l-am întâlnit în capitolul
precedent, dar într-o cu totul altă ipostază – testarea încadrării valorii unui atribut într-o listă de constante.
În continuare, domeniul de testare este alcătuit din liniile unei tabele.

Exemplu:
Ce studenţi studiază la aceeaşi secţie cu „Danciu Daria”?

SELECT STUDENT.nume, STUDENT.Sectia


FROM STUDENT
WHERE (((STUDENT.[sectia]) In
(SELECT sectia FROM STUDENT
WHERE nume = "Danciu Daria")));

În cazul acestei interogări, execuţia se realizează în doi timpi. Mai întâi se execută subconsultarea

SELECT sectia
FROM STUDENT
WHERE nume = „Danciu Daria”

obţinându-se o tabelă intermediară ce conţine o singură linie (pe care apare Danciu Daria) şi o singură
coloană (sectia) În cel de-al doilea pas sunt selectate liniile tabelei STUDENT care îndeplinesc condiţia
sectia = „CIG”

nume Sectia
Buciumeanu Olivia CIG
Popescu Liviu CIG
Danciu Daria CIG

Observăm că în rezultat a fost inclus şi studentul de referinţă – Danciu Daria. Dacă se doreşte
excluderea din rezultat a acestui student, fraza SELECT se modifică astfel:
SELECT STUDENT.nume, STUDENT.Sectia
FROM STUDENT
WHERE (((STUDENT.nume)<>"Danciu Daria") AND ((STUDENT.[sectia]) In
(SELECT sectia FROM STUDENT
WHERE nume = "Danciu Daria")));

Exemplu:
Ce studenţi studiază la alte secţii decât „Danciu Daria”?

SELECT STUDENT.nume, STUDENT.Sectia


FROM STUDENT
WHERE (((STUDENT.[sectia]) Not In
(SELECT sectia FROM STUDENT
WHERE nume = "Danciu Daria")));
nume Sectia
Iancu Loredana MG
Sitaru Ionut MG
Musat Florin MK
Soare Paul GEOGRAFIE
Bojianu Mirela FB
Balasa Mihai ECTS
Tudorache Ionelia FB
Neacsu Florin MG
Radu Marta MK
Stanciu Andreea DREPT
Zamfir Octavian ECTS
Stanciu Mirela MK
Bobeica Lidia MG
Sandu Georgeta DREPT
Ionescu Octavian ISTORIE
Butu Ion JURNALISM
Vasilescu Ada ISTORIE

Exemplu:
În ce cămin sunt cazaţi studenţii care studiază la aceeaşi secţie cu „Danciu Daria”?

SELECT DISTINCT STUDCAMIN.[nume camin]


FROM STUDCAMIN
WHERE (((STUDCAMIN.[numar matricol]) In
(SELECT [numar matricol] FROM STUDENT
WHERE sectia IN
(SELECT sectia FROM STUDENT
WHERE nume = "Danciu Daria"))));

nume camin
Caminul nr. 1
Caminul nr. 2
Caminul Sportiv

Exemplu:
Din ce judeţe sunt studenţii care au împrumutat cărţi scrise de autori de naţionalitate română?

Am ales acest exemplu pentru a folosi în subconsultări cât mai multe tabele ale bazei de date:
SELECT distinct judet FROM LOCALITATE
WHERE [cod localitate] IN
(SELECT [cod localitate] FROM STUDENT
WHERE [numar matricol] IN
(SELECT [numar matricol] FROM
STUDCARTE WHERE [cota carte] IN
(SELECT [cota carte] FROM CARTE
WHERE [cota carte] IN
(SELECT [cota carte]
FROM
AUTORCARTE WHERE
[cod autor] IN
(SELECT [cod autor] FROM
AUTOR
WHERE nationalitate =
"roman")))))

judet
Arges
Constanta
Dambovita
Gorj
Iasi
Suceava
Timisoara

S-ar putea să vă placă și