Sunteți pe pagina 1din 13

Ministerul Educaţiei, Culturii şi Cercetării al Republicii Moldova

Universitatea Liberă Internaţională din Moldova

Facultatea Informatică, Inginerie şi Design

Disciplina: Baze de Date

Lucrare de laborator Nr.6

Tema: Crearea interogărilor din mai multe tabele


concomitent

A efectuat

Student gr. TIR-26

Pîrlog Andrei

A verificat

Profesor Vitalii MITITELU

Chişinău 2018
1. Scopul lucrării:

Crearea interogărilor din mai multe tabele concomitent

2. Sarcina:

Scopul: crearea interogărilor și gruparea lor.

Sarcini
1. Afișați pe ecran cel mai mare, cel mic, suma și valoarea medie a salariului tuturor
angajaților. Numiți aceste câmpuri Maxim, Minim, Sumă și Medie respectiv.
Rotunjiți rezultatul până la cel mai apropiat număr întreg.
2. Modificați interogarea precedentă astfel, încât să arate cel mai mare, cel mic, suma
și valoarea medie a salariului pentru fiecare funcție.
3. Scrieți o interogare care afișează pe ecran numărul de angajați cu același serviciu.
4. Calculați numărul managerilor întreprinderii, fără a-i afișa pe ei însăși. Numiți
acest câmp Număr de Manageri. Notă: folosiți câmpul Man_ID pentru a determina
numărul de manageri.
5. Scrieți o interogare care afișează pe ecran diferența dintre cel mai mare și cel mai
mic salariu. Numiți această coloană Diferență.
6. Scrieți o interogare care afișează pe ecran numărul managerului și salariul
angajatului cl mai rău plătit al acestui manager. Excludeți angajații, managerul
cărora nu este cunoscut. Excludeți toate înregistrările, la care salariul minimal este
6000 sau mai puțin. Sortați datele descrescător după salariu.
7. Scrieți o interogare care afișează pe ecran denumirea departamentului, Loc_ID,
numărul de angajați și salariul mediu pentru toți angajații acestui departament.
Numiți aceste câmpuri Nume, Locație, Număr de Persoane și Salariu respectiv.
Rotunjiți salariul mediu până la două cifre după virgulă.
8. Scrieți o interogare care afișează pe ecran numărul general de angajați, precum și
numărul de angajați primiți la serviciu în 2005, 2006, 2007 și 2008. Numiți aceste
câmpuri TOTAL, 2005, 2006, 2007 și 2008 respectiv.
9. Scrieți o interogare matriceală, care afișează pe ecran funcția și salariul acestei
funcții, bazat pe numărul departamentului și salariul total al acestei funcții pentru
departamentele 10, 20, 40 și 50. Numiți aceste câmpuri Funcție, Dept 10, Dept 20,
Dept 40, Dept 50 și Total (această coloană este suma tuturor datelor din baza
noastră de date, nu doar a precedentelor patru coloane) respectiv. Exemplu de
rezultat:

Funcție Dept 10 Dept 20 Dept 40 Dept 50 Total


AD_PRES 15000 15000
ST_MAN 12000 13000 6000 31000
IT_PROG 9500 10300 35600
SA_REP 8000 8000
ST_CLERK 16300
3. Parte teoretică:

Lista ţintă - specifică elementele schemei tabelelor rezultat.

Caracterul special * poate să apară în lista ţintă şi reprezintă selecţia tuturor atributelor
tabelelor precizate în clauza from. Lista ţintă poate conţine expresii ce utilizează valorile
atributelor din fiecare linie selectată.

Clauza from

Dacă o interogare implică înregistrări din mai multe tabele, argumentul din clauza from va
reprezenta o listă de tabele. Condiţiile din clauza where sunt aplicate în acest caz produsului
cartezian al acestor tabele; se poate specifica o joncţiune prin indicarea explicită a
comparaţiilor între atribute din tabele diferite.În interogarea precedentă s-a folosit operatorul
punct (’.’) pentru identificarea tabelului din care se extrag atributele.

Folosirea acestei construcţii este necesară în cazul în care tabelele din clauza from au atribute
cu acelaşi nume, pentru a distinge între referinţele la atribute omonime.

În cazul în care nu există posibilitatea apariţiei unei ambiguităţi se poate specifica atributul
fără a preciza tabelul căruia îi aparţine. Într-o interogare se pot utiliza alias-uri pentru tabele
cu scopul de a scurta referinţa la acestea.

Clauza where

Condiţia din clauza where este o expresie booleană formată prin combinarea predicatelor
simple cu operatorii and, or şi not. Fiecare predicat simplu utilizează operatorii de comparaţie
(=, >, >=, <, <=, <>) şi are, într-un membru, o expresie formată din valori ale atributelor dintr-
o linie şi în celălalt membru o valoarea constantă sau o altă expresie. Prioritar este operatorul
not, dar nu se introduce o precedenţă între and şi or. Dacă într-o expresie se folosesc ambii
operatori and şi or este indicată specificarea precedenţei prin utilizarea parantezelor.

Operatorul like - pentru compararea şirurilor de caractere

Acest operator compară un şir cu alt şir, specificat parţial cu ajutorul caracterelor speciale ’_’
şi ’%’. • Caracterul ’_’ substituie un caracter oarecare • Caracterul ’%’ substituie un şir
oarecare de caractere, posibil vid.

Gestiunea valorilor NULL Predicatul is NULL este adevărat doar dacă atributul are valoarea
NULL. Predicatul is not NULL este adevărat în caz contrar celui prezentat anterior.

Sintaxa: Atribut is [not] NULL

Duplicate

În SQL un tabel poate avea mai multe linii ce conţin aceleaşi valori pentru toate atributele
(duplicate), spre deosebire de algebra relaţională şi calculul relaţional. Dacă se doreşte
emularea comportării din algebra relaţională în SQL ar trebui eliminate toate duplicatele la
fiecare execuţie a unei operaţii de proiecţie. Deoarece operaţia de eliminare a duplicatelor
este consumatoare de timp şi adesea nu este necesară, executarea acestei operaţii este lăsată la
latitudinea persoanei ce implementează interogarea. Sintaxa eliminarea duplicatelor: select
[<distinct | [all]>] Opţiunea all indică faptul că vor fi păstrate toate înregistrările din rezultat
(deci inclusiv duplicatele) şi este opţiunea implicită.
Joncţiuni

SQL-2 introduce o sintaxă alternativă pentru specificarea joncţiunilor, fiind astfel posibilă
realizarea unei distincţii între condiţiile ce reprezintă condiţii de joncţiune şi cele ce reprezintă
selecţii de linii. Sintaxa este:

select ExprAtribut [[as] Alias] {, ExprAtribut [[as] Alias]} from NumeTabel [[as] Alias]
{[TipJonctiune] join NumeTabel [[as] Alias] on CondJonctiune} [where AlteConditii]

În acest fel, condiţia de joncţiune este mutată din clauza where în clauza from. Parametrul
TipJonctiune specifică tipul joncţiunii: inner, left sau full. Inner join corespunde theta-
joncţiunii din algebra relaţională. În cazul unei joncţiuni, liniile dintr-un tabel ce nu au linii
corespondente în celălalt tabel vor fi eliminate din rezultat. Pentru a forţa apariţia unor astfel
de linii în rezultat se poate apela la joncţiunea externă, cu cele trei variante: • left join –
furnizează acelaşi rezultat ca şi inner join, dar include şi liniile tabelului ce apare în stânga
joncţiunii pentru care nu există linii corespondente în tabelul din dreapta; • right join –
păstrează liniile tabelului din dreapta ce nu au corespondent în tabelul din stânga; • full join –
furnizează acelaşi rezultat ca şi inner join, suplimentat cu liniile excluse din ambele tabele.

Unele implementări de SQL specifică joncţiunea externă prin adăugarea unui caracter special
sau a unei secvenţe de caractere (* sau (+)) la atributele implicate în condiţia de joncţiune.

Utilizarea variabilelor

Prin folosirea alias-urilor se poate referi un tabel de mai multe ori, într-un mod similar
operatorului de redenumire ρ din algebra relaţională. Când este introdus un alias, se declară o
variabilă tip tabel care are ca valoare conţinutul tabelului pentru care se introduce alias-ul.
Când un tabel apare doar o singură dată în interogare, nu este nici o diferenţă între a interpreta
alias-ul ca pseudonim sau ca o nouă variabilă. Când tabelul apare de mai multe ori este
esenţial să privim alias-ul ca o nouă variabilă.

Utilizarea alias-urilor de tabel are importanţă din următoarele puncte de vedere:

• se evită necesitatea scrierii întregului nume al tabelului ori de câte ori este cerut acest lucru;

• se poate face referire de mai multe ori la acelaşi tabel; introducerea unui alias are
semnificaţia declarării unei variabile de tip tabel, ce are acelaşi conţinut cu tabelul al cărui
alias este;

• se pot specifica cererile imbricate.

Ordonarea În general, rezultatul unei interogări conţine linii, aranjate într-o ordine oarecare.
Dacă se doreşte impunerea unei ordonări după un anumit criteriu asupra liniilor returnate de o
interogare se va utiliza clauza order by.

Sintaxa este: order by Atribut [asc | desc] {, Atribut [asc | desc]}

Operatorii agregaţi constituie una din cele mai importante extensii ale SQL în comparaţie cu
algebra relaţională. În algebra relaţională toate condiţiile sunt evaluate pentru un singur tuplu
la un moment dat. Adesea apare necesitatea evaluării unor proprietăţi ce depind de o mulţime
de tupluri (de exemplu aflarea numărului de angajaţi ce lucrează în departamentul Producţie).
Operatorii agregaţi sunt:

• count Sintaxă: count ( < * | [distinct | all] ListaAtribute>)


• Opţiunea * returnează numărul de linii din rezultat.

• Opţiunea distinct returnează numărul valorilor distincte pentru lista de atribute din rezultat.

• Opţiunea all returnează numărul liniilor ce conţin valori diferite de NULL pentru lista de
atribute.

Dacă se specifică un atribut fără un distinct sau all se consideră opţiunea implicită all.

Interogări group by

Funcţiile agregat prezentate operează pe toate liniile returnate de interogare. În cazul în care
se doreşte utilizarea funcţiilor agregat pe o submulţime a liniilor selectate SQL pune la
dispoziţie clauza group by. Această clauză specifică modul în care va fi împărţit tabelul în
submulţimi de linii. Clauza acceptă ca argument o mulţime X de atribute, iar interogarea va
opera separat pe fiecare mulţime de linii ce posedă aceleaşi valori pentru X.

Interogări imbricate

Până acum toate interogările formulate conţineau în clauza where o condiţie compusă, în
care fiecare predicat reprezintă o comparaţie între două valori. Se pot defini predicate cu
structură complexă, în care o expresie valorică poate fi comparată cu rezultatul execuţiei unei
interogări SQL. Interogarea utilizată în comparaţie se defineşte în interiorul predicatului din
clauza where şi se numeşte interogare imbricată. În general, primul operand al unei comparaţii
de genul celei amintite anterior este un atribut, în timp ce în celălalt membru avem o mulţime
de valori (rezultatul interogării). Pentru a rezolva această problemă a eterogenităţii termenilor
comparaţiei, SQL pune la dispoziţie cuvintele cheie any şi all pentru a extinde operatorii de
comparaţie. any - specifică faptul că linia este validă dacă valoarea atributului se află în
relaţie cu cel puţin o valoare returnată de interogarea imbricată. all - specifică faptul că linia
este validă dacă valoarea atributului se află în relaţie cu toate valorile returnate de interogare.
Sintaxa cere ca domeniul elementelor returnate de interogarea imbricată să fie compatibil cu
atributul cu care se face comparaţia.

Operatorii in şi not in - reprezintă apartenenţa la o mulţime. Aceşti operatori sunt echivalenţi


cu = any, respectiv <> all. Să mai facem observaţia că funcţiile agregat max şi min pot fi
utilizate în interogările imbricate

Pentru a înţelege mecanismul rezolvării interogărilor ce conţin interogări imbricate se pleacă


de la presupunerea că interogarea imbricată se execută înaintea analizei liniilor din
interogarea externă. Rezultatul interogării poate fi salvat într-o variabilă temporară şi
predicatul interogării externe poate fi evaluat cu ajutorul rezultatului temporar. Uneori
interogarea imbricată face referire la contextul interogării în care este imbricată; acest lucru
are loc prin intermediul unei variabile definită în interogarea externă şi utilizată în cea internă.
Un astfel de mecanism este cunoscut sub numele de transferul legăturilor dintr-un context în
altul. În acest caz, noua interpretare pentru interogările imbricate este următoarea: pentru
fiecare linie din interogarea externă se evaluează mai întâi interogarea imbricată şi apoi se
evaluează predicatul din interogarea externă.

Vizibilitatea variabilelor SQL

O variabilă poate fi utilizată doar în interiorul interogării în care este definită sau în
interogarea imbricată din interogarea în care este definită. Dacă o interogare conţine
interogări imbricate pe acelaşi nivel, variabilele declarate în clauza from a unei interogări nu
pot fi utilizate în contextul celeilalte interogări.

O altă cale de a formula interogarea din exemplul anterior este prin folosirea constructorului
de tuplu, reprezentat de o pereche de paranteze rotunde care marchează lista de atribute.

Sistemele comerciale nu rezolvă întotdeauna interogările imbricate prin scanarea tabelului


extern şi producerea unei interogări pentru fiecare linie din relaţie. În schimb se încearcă
procesarea cât mai multor interogări într-o manieră orientată pe mulţimi, cu scopul de a
manevra cantităţi mari de date prin cât mai puţine operaţii posibile.

Clauzele comenzii trebuie utilizate în ordinea specificată în sintaxă, excepţie făcând


clauzele CONNECT BY, START WITH, GROUP BY şi HAVING (care pot fi specificate în
orice ordine). Clauzele ORDER BY şi FOR UPDATE OF pot fi schimbate între ele. Clauza
ALL determină afişarea tuturor rândurilor rezultate în urma cererii, spre deosebire de clauza
DISTINCT care determină eliminarea duplicatelor, afişînd doar rândurile distincte. Utilizarea
caracterului asterisc (*) are ca efect selectarea tuturor coloanelor din tabela specificată prin
clauza FROM, în ordinea în care au fost definite la creare. În situaţia finală, fiecare expresie
formulată în comandă devine un nume de coloană. Totodată, orice sinonim, dacă este
specificat, este folosit în scopul etichetării expresiei precedente din tabela afişată. Dacă
sinonimul conţine blancuri sau caractere speciale cum sunt “+” şi ”-“, trebuie incluse între
apostrofuri. Pentru a evita ambiguitatea, în cazul în care tabelele conţin coloane cu acelaşi
nume, este necesară calificarea coloanelor cu numele tabelei .

Identificarea tabelelor în care trebuie căutate datele corespunzătoare coloanelor


specificaţi se face prin specificarea numelor lor după clauza FROM. În locul numelor de
tabele se pot folosi sinonimele acestora. Clauza WHERE specifică o condiţie care este folosită
pentru a selecta rândurile. Clauza CONNECT BY indică faptul că rândurile formează o
structură arborescentă. Prin această clauză sunt definite relaţiile necesare pentru a conecta
rândurile tabelei într-un arbore. Operatorul PRIOR folosit înaintea uneia din cele două părţi
ale condiţiei, defineşte nodul părinte iar în cealaltă parte nodul fiu. Clauza START WITH,
prin specificarea unei condiţii care trebuie satisfăcută, stabileşte rândul folosit ca rădăcină a
arborelui. Dacă se omite, comanda SELECT va returna o serie de arbori începând cu fiecare
rând selectat. Existenţa clauzei CONNECT BY într-o comandă SELECT permite utilizarea
pseudocoloanei LEVEL, care returnează valoarea 1 pentru nodul rădăcină, 2 pentru fiii
nodului rădăcină, 3 pentru nepoţi etc. Clauzele GROUP BY şi HAVING determină afişarea
unor informaţii sintetice despre grupuri de rânduri care au aceeaşi valoare în una sau mai
multe coloane. Aceste coloane sunt, în general, funcţii de grup. ROLLUP activează o
comanda SELECT pentru a calcula mai multe niveluri de subtotaluri dintr-un grup specificat
de dimensiuni. Calculează de asemenea şi un total general. ROLLUP este o extensie simplă a
clauzei GROUP BY, deci sintaxa este foarte uşor de folosit. Extensia ROLLUP este foarte
eficientă şi nu îngreunează o cerere. Rolul extensiei ROLLUP este foare clar: crează
subtotaluri care pornesc de la cel mai detaliat nivel până la un total general după gruparea care
a fost precizată în clauza ROLLUP. CUBE acţionează asupra unui grup specificat de coloane
şi crează subtotaluri pentru toate combinaţiile posibile între acestea. Dacă sa specificat de
exemplu: CUBE (timp,regiune, department), rezultatul va include toate valorile care ar fi
incluse într-un ROLLUP plus combinaţii adiţionale. Pentru a combina rezultatele a două
comenzi SELECT într-un singur rezultat, se folosesc operatorii UNION, INTERSECT şi
MINUS. UNION returnează rezultatele obţinute de la fiecare cerere în parte, INTERSECT
returnează doar rezultatele comune celor două cereri iar MINUS returnează rezultatele
obţinute de la prima cerere şi care nu apar în urma celei de a doua selecţii.

Pentru a putea folosi aceste clauze este necesar ca numărul şi tipul coloanelor selectate de
fiecare comandă SELECT să fie aceleaşi, lungimile lor putând fi diferite. Dacă sunt
combinate mai mult de două comenzi SELECT, ele vor fi evaluate de la stînga la dreapta.
Pentru a schimba ordinea de evaluare pot fi folosite parantezele. Totodată, cei trei operatori
impun utilizarea cuvântului DISTINCT în toate comenzile SELECT. Clauza ORDER BY
specifică ordinea în care trebuie returnate rândurile distincte ale unei tabele. Clauza FOR
UPDATE determină blocarea rândurilor selectate ale tabelei astfel încât acestea nu vor mai
putea fi actualizate de alţi utilizatori până la deblocarea lor cu una din comenzile COMMIT
sau ROLL BACK. Comanda SELECT ... FOR UPDATE trebuie urmată de una sau mai multe
comenzi UPDATE ... WHERE. Dacă se foloseşte clauza NOWAIT, selecţia este considerată
terminată chiar dacă rândurile selectate de FOR UPDATE nu pot fi blocate deoarece alt
utilizator lucrează cu ele.

4. Mersul lucrări

1. Afișați pe ecran cel mai mare, cel mic, suma și valoarea medie a salariului tuturor
angajaților. Numiți aceste câmpuri Maxim, Minim, Sumă și Medie respectiv. Rotunjiți
rezultatul până la cel mai apropiat număr întreg.
SELECT ROUND(MAX(SALARIU)) AS Maxim , ROUND(MIN(SALARIU)) AS Minim ,
ROUND(SUM(SALARIU)) AS Suma, ROUND(AVG(SALARIU)) AS MEDIE
FROM ANGAJATI

2. Modificați interogarea precedentă astfel, încât să arate cel mai mare, cel mic, suma și
valoarea medie a salariului pentru fiecare funcție.
SELECT ROUND(MAX(SALARIU)) AS Maxim, ROUND(MIN(SALARIU)) AS Minim,
ROUND(SUM(SALARIU)) AS SUMA, ROUND(AVG(SALARIU)) AS MEDIE,
FUNCTII.FUNC_ID, FUNCTII.FUNC_DEN
FROM ANGAJATI
LEFT JOIN FUNCTII ON ANGAJATI.FUNC_ID = FUNCTII.FUNC_ID
GROUP BY FUNCTII.FUNC_DEN, FUNCTII.FUNC_ID
3. Scrieți o interogare care afișează pe ecran numărul de angajați cu același serviciu.

4. Calculați numărul managerilor întreprinderii, fără a-i afișa pe ei însăși. Numiți acest câmp
Număr de Manageri. Notă: folosiți câmpul Man_ID pentru a determina numărul de
manageri.
SELECT COUNT(MAN_ID) AS "Numărul de Manageri" FROM ANGAJATI
JOIN FUNCTII ON ANGAJATI.FUNC_ID = FUNCTII.FUNC_ID AND
FUNCTII.FUNC_DEN = 'Manager'
5. Scrieți o interogare care afișează pe ecran diferența dintre cel mai mare și cel mai mic
salariu. Numiți această coloană Diferență.
SELECT ROUND(MAX(SALARIU)-MIN(SALARIU)) AS "Diferență"
FROM ANGAJATI

6. Scrieți o interogare care afișează pe ecran numărul managerului și salariul angajatului cl


mai rău plătit al acestui manager. Excludeți angajații, managerul cărora nu este cunoscut.
Excludeți toate înregistrările, la care salariul minimal este 6000 sau mai puțin. Sortați
datele descrescător după salariu.

SELECT ANGAJATI.MAN_ID, MIN(salariu)


FROM ANGAJATI
WHERE ANGAJATI.MAN_ID IS NOT NULL
GROUP BY ANGAJATI.MAN_ID
HAVING MIN(SALARIU) > 6000
ORDER BY MIN(SALARIU) DESC
7. Scrieți o interogare care afișează pe ecran denumirea departamentului, Loc_ID, numărul
de angajați și salariul mediu pentru toți angajații acestui departament. Numiți aceste
câmpuri Nume, Locație, Număr de Persoane și Salariu respectiv. Rotunjiți salariul mediu
până la două cifre după virgulă.

SELECT b.DEP_DEN "NUME" , b.LOC_ID "LOCATIE" , COUNT (ANG_ID) "NUMAR


DE PERSOANE" ,ROUND (AVG(SALARIU),2) SALARIU
FROM ANGAJATI a, DEPARTAMENTE b
WHERE a.DEP_ID = b.DEP_ID
GROUP BY b.DEP_ID , b.DEP_DEN , LOC_ID
8. Scrieți o interogare care afișează pe ecran numărul general de angajați, precum și
numărul de angajați primiți la serviciu în 2005, 2006, 2007 și 2008. Numiți aceste
câmpuri TOTAL, 2005, 2006, 2007 și 2008 respectiv.
SELECT EXTRACT(YEAR FROM DATA_ANG) AS "Anul", count(*) as "Total"
FROM ANGAJATI
where EXTRACT(YEAR FROM DATA_ANG)= 2005 or EXTRACT(YEAR FROM
DATA_ANG)=2006 or EXTRACT(YEAR FROM DATA_ANG)=2007 or EXTRACT(YEAR
FROM DATA_ANG)=2008
group by EXTRACT(YEAR FROM DATA_ANG)

9. Scrieți o interogare matriceală, care afișează pe ecran funcția și salariul acestei funcții,
bazat pe numărul departamentului și salariul total al acestei funcții pentru departamentele
10, 20, 40 și 50. Numiți aceste câmpuri Funcție, Dept 10, Dept 20, Dept 40, Dept 50 și
Total (această coloană este suma tuturor datelor din baza noastră de date, nu doar a
precedentelor patru coloane) respectiv. Exemplu de rezultat:

Funcție Dept 10 Dept 20 Dept 40 Dept 50 Total


AD_PRES 15000 15000
ST_MAN 12000 13000 6000 31000
IT_PROG 9500 10300 35600
SA_REP 8000 8000
ST_CLERK 16300

SELECT a.*,(SELECT SUM(SALARIU)


FROM ANGAJATI
WHERE FUNC_ID = a.FUNC_ID
GROUP BY FUNC_ID)
TOTAL
FROM (SELECT FUNC_ID,dep_id,sum(SALARIU) SAL from ANGAJATI
GROUP BY FUNC_ID,DEP_ID)
PIVOT
(SUM(SAL) FOR DEP_ID IN (10 AS "DEPT 10",20 AS "DEPT 20",40 AS "DEPT 40",50
AS "DEPT 50")) a
ORDER BY FUNC_ID;
Concluzie

În urma efetuării lucrării de laborator am observat cît de rapid este posibil de creat un tabel într-o
bază de date cu ajutorul comenzilor şi utilizarea funcţiilor de diverse tipuri pentru scrierea
interogărilor. Cu ajutorul interogarilor poti aplica o mulţime de comenzi.

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