Sunteți pe pagina 1din 9

FUNCII DE GRUP ORACLE

Pentru exemplificarea fundamentelor SQL care stau la baza


interpretrii rezultatelor economice obinute n urma
prelucrii datelor din sistemul economic sunt foarte des
utilizate funciile de grup COUNT, MAX, MIN, SUM, AVG,
STDDEV, VARIANCE precum i clauzele ROLLUP, CUBE,
GROUPING, GROUP BY, HAVING - care permit o analiz
economic detaliat a rezultatelor obinute.

12/27/2012
CUPRINS

Noiuni teoretice ...................................................................................................................................... 3


Funcia COUNT(exp) ............................................................................................................................... 3
Funcia MAX(exp) .................................................................................................................................... 3
Funcia MIN(exp) ..................................................................................................................................... 3
Funcia AVG(exp) ..................................................................................................................................... 3
Funcia SUM(exp) .................................................................................................................................... 3
Aplicaii ....................................................................................................................................................... 4
Fia nr.1....................................................................................................................................................... 4
Clauza GROUP BY ..................................................................................................................................... 5
Clauza HAVING .......................................................................................................................................... 6
Subtotaluri ................................................................................................................................................. 6
Fia nr. 2 ...................................................................................................................................................... 7
Fia nr. 3 ...................................................................................................................................................... 8
Rezolvarea fiei nr. 1 .............................................................................................................................. 9
Rezolvarea fiei nr. 2 .............................................................................................................................. 9
Noiuni teoretice
Funciile de grup returneaz o singur valoare pentru un grup sau set de linii
dintr-un tabel. Cu ajutorul acestor funcii putem calcula valoarea minim sau valoarea
maxima dintr-un set de valori, putem determina numarul de nregistrari ce respecta o
anumita condiie etc. Funciile de grup ignora valorile nule.

Funcia COUNT(exp)
C
- determin numrul de valori ale lui exp. Aceast funcie poate fi folosit n combinaie cu U
clauza DISTINCT, pentru a numra doar valorile distincte dintr-un domeniu.Exemple: P
SELECT COUNT(job) FROM EMP R
SELECT COUNT(DISTINCT(job)) FROM EMP I
N
Funcia MAX(exp) S

-determin valoarea maxim a valorilor expresiei exp. Exemplu:


SELECT MAX(sal) FROM emp
SELECT MAX(hiredate) FROM emp

Funcia MIN(exp)

-determin valoarea minim a valorilor expresiei exp. Exemplu:


SELECT MIN(sal) FROM emp
SELECT MIN(hiredate) FROM emp

Funcia AVG(exp)

-determin media valorilor expresiei exp. Exemplu:


SELECT AVG(sal) FROM emp
SELECT AVG(comm), AVG(NVL(comm,0)) FROM emp

Funcia SUM(exp)

-determin suma valorilor expresiei exp.Exemplu:


SELECT SUM(sal) FROM emp
SELECT SUM(sal) FROM emp WHERE job='MANAGER'
Aplicaii
Deschide baza de date Oracle i urmrete rezultatul afiat de interogrile de mai jos:

SELECT AVG(sal), MAX(sal),MIN(sal), SUM(sal) FROM emp WHERE job='SALESMAN'

SELECT MIN(ename), MAX(ename) FROM emp


C
SELECT MIN(hiredate), MAX(hiredate) FROM emp WHERE sal BETWEEN 1500 AND U
2500 P
R
SELECT COUNT(*) FROM emp WHERE COMM IS NOT NULL I
N
SELECT MAX(hiredate)-MIN(hiredate) FROM emp S

SELECT MAX(sal),MIN(sal),MAX(sal)-MIN(sal) FROM emp WHERE hiredate BETWEEN


'01.01.1982' AND '01.01.1985'

Fia nr.1 Rezolvarea fiei nr. 1

1. Afiai salariul mediu, maxim, minim i suma tuturor salariilor angajailor cu job
MANAGER.
2. Afiai datele(ziua i luna, n format monday 06, september) la care s-au fcut prima
i ultima angajare n anul 1982.
3. Afiai primul i ultimul nume de angajat n ordine alfabetic.
4. Afiai numrul angajailor care iau comision din departamentul 30.
5. Afiai numrul de departamente din firm.
6. Afiai numrul de funcii din firm.
7. Afiai numrul de persoane angajate n 1981.
Clauza GROUP BY
Pentru a putea mpri tabela n grupuri mai mici se folosete clauza GROUP BY. Folosirea
acesteia returneaz informaii despre fiecare grup. Exemplu:

SELECT deptno, MAX(sal), MIN(sal) FROM emp GROUP BY deptno

Comanda de mai sus afieaz salariul maxim i salariul minim pentru fiecare departament.

Reguli de folosire a clauzei GROUP BY:


- n clauza GROUP BY nu se accept un alias de coloan; C
- toate cmpurile care apar n clauza SELECT trebuie s apar i n clauza GROUP BY; U
- NU SE FOLOSESC funcii de grup n clauza WHERE; P
- n clauza GROUP BY pot s apar i coloane care nu sunt n clauza SELECT. R
I
Exemple: N
S
1)SELECT deptno AS DEPARTAMENT, MAX(sal) FROM emp GROUP BY DEPARTAMENT
Comanda de mai sus va genera o eroare deoarece nu respect prima regul. Comanda
corect este:
SELECT deptno AS DEPARTAMENT, MAX(sal) FROM emp GROUP BY deptno

2)SELECT deptno ,job, MAX(sal) FROM emp GROUP BY deptno


Comanda de mai sus va genera o eroare deoarece nu respect a doua regul. Comanda
corect este:
SELECT deptno ,job, MAX(sal) FROM emp GROUP BY deptno,job

3) SELECT job, MAX(sal) FROM emp WHERE MAX(sal)>1500 GROUP BY job


Comanda de mai sus va genera o eroare deoarece nu respect a treia regul. Comanda
corect se scrie cu ajutorul clauzei HAVING:
SELECT job, MAX(sal) FROM emp GROUP BY job HAVING MAX(sal)>1500

4)SELECT AVG(MAX(sal)) FROM emp GROUP BY deptno


Clauza HAVING
Pentru a filtra grupurile obinute cu ajutorul clauzei GROUP BY, se folosete clauza HAVING.
Clauza HAVING funcioneaz n mare ca i clauza WHERE, diferena fiind c, HAVING este
folosit pentru a exclude anumite grupuri din rezultat, nu rnduri cum face WHERE. Clauza
HAVING poate fi folosit nainte de GROUP BY, ns este mai logic s fie folosit dup.
Ordinea de execuie va rmne aceeai.

Exemplu:

SELECT job, SUM(sal) FROM emp C


WHERE job!='SALESMAN' U
GROUP BY job P
HAVING SUM(sal) > 2500 R
ORDER BY SUM(sal) I
Comanda de mai sus afieaz funciile i salariul total pe fiecare funcie, fr a lua in calcul N
angajaii cu funcia SALESMAN i excluznd funciile cu suma salariilor sub 2500 cu S
ordonare dup salariul total.

Subtotaluri
Pentru a efectua sinteze a datelor pe baza totalurilor pariale folosim clauzele ROLLUP i
GROUPING. Clauza ROLLUP este inclus n clauza GROUP BY, argumentele acesteia fiind
coloanele de grupare. Clauza GROUPING este inclus n clauza SELECT, argumentul acesteia
fiind coloana de grupare. Rezultatul ntors de aceast clauz este 1 atunci cnd coloana
respectiv este inclus ntr-un grup de agregare superior sau 0 pentru liniile din afara
subtotalurilor.Exemplu:
SELECT
CASE
WHEN GROUPING(job)=1 THEN 'Nr. total angajati'
WHEN GROUPING(ename)=1 THEN 'Nr. angajati pe functia de '
ELSE
ename
END NUME, job FUNCTIA, COUNT(empno) NUMAR FROM EMP
GROUP BY ROLLUP(job,ename)
Deschide baza de date Oracle i urmrete rezultatul afiat de interogarea de mai sus.
Fia nr. 2 Rezolvarea fiei nr. 2

Deschide baza de date Oracle i urmrete rezultatul afiat de interogrile de mai jos:

1) SELECT deptno, COUNT(empno) FROM emp GROUP BY deptno


2) SELECT deptno, ROUND(AVG(sal),4) FROM emp GROUP BY deptno
3) SELECT AVG(MIN(sal)) FROM emp GROUP BY empno
4) SELECT deptno, SUM(sal) FROM emp GROUP BY deptno ORDER BY SUM(sal) DESC
5) SELECT job, ROUND(AVG(sal),4) FROM emp GROUP BY job HAVING AVG(sal)<2200

Exerciii C
1. Afiai salariul maxim, minim, suma salariilor i salariul mediu pentru fiecare funcie. Care este U
diferena ntre salariul maxim i salariul minim pentru fiecare funcie? P
R
2. Determinai numrul de angajai cu aceeai funcie. I
3. Determinai numrul de manageri(Folosii cmpul MGR). N
4. Afisati id-ul managerului si salariul celui mai slab platit angajat al acelui manager. Excludeti pe S
oricine al carui manager nu este cunoscut si orice grup unde salariul minim este 1000 sau mai
putin. Sortati rezultatele in ordinea descrescatoare a salariilor minime.
5. Creai o interogare care s afieze numele angajatului, funcia, salariul total(SUBTOTAL) pentru
acea funcie i totalul general obinut.
6. Modificai interogarea de mai sus astfel nct, s afieze numele angajatului, numrul
departamentului, salariul total pe fiecare departament i totalul general.
7. Modificai interogarea de mai sus astfel nct, s afieze numele angajatului, numrul
departamentului, funcia, salariul total pe fiecare departament i pe fiecare funcie precum i
totalul general.
8. Afiai numrul total de angajai si apoi numrul de persoane angajate n anii 1980, 1981, 1982,
1983 si 1984. Pentru rezolvarea acestui exerciiu se folosesc SUBINTEROGRI scalare
(subinterogare ce returneaz o singur linie/coloan(vezi mai jos rezolvarea).
SELECT
(SELECT COUNT(empno) FROM emp) NR_TOTAL,
(SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1980') AS "1980",
(SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1981') AS "1981",
(SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1982') AS "1982",
(SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1983') AS "1983",
(SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1984') AS "1984"
FROM DUAL
Fia nr. 3
Deschide baza de date Oracle i rezolv interogrile de mai jos:

1) Afiai numele departamentului i numrul de angajai pentru fiecare departament.


2) Afiai numele departamentului i valoarea total a salariilor pentru fiecare
departament.
3) Modificai interogrile de mai sus astfel nct s se afieze i totalul general1.
4) Creai o interogare care s afieze numele departamentului, funcia, salariul total
(SUBTOTAL) pentru acea funcie i totalul general obinut.2
5) Modificai interogarea de mai sus astfel nct s elimine orice grup unde salariul total
este 2000 sau mai puin.3 C
6) Afiai numrul de angajai pe orae. U
7) Afiai urmtoarea propoziie:IN DEPARTAMENTUL dname DIN ORASUL loc SUNT P
numar ANGAJATI. VALOAREA TOTALA A SALARIILOR ACESTORA ESTE DE suma. S R
se afieze i totalul general. I
8) S se afieze numele departamentului i primele dou salarii maxime din fiecare N
departament. S
9) Afiai numele managerilor i numrul de angajai pe care i are n subordine fiecare
manager.
10)Modificai interogarea de mai sus astfel nct s afieze pentru fiecare manager,
numele acestuia, numele angajailor i numrul lor.
11)Dac salariul angajailor crete la implinirea a 32 ani vechime cu 10%, afiati numrul
de angajai care au astzi aceast vechime i valoarea noului salariu.
12)Presupunnd c salariul se mrete cu fiecare lun ce trece de la data angajrii cu
0.15%, iar salariul stocat n baza de date e cel primit la data angajrii, care a fost
valoarea total a salariilor la data de 1 ianuarie 2013 (afiai valoarea total a
salariilor iniiale i valoarea total a salariilor la data de 01.01.2013, cu dou
zecimale) ?
13) Considerm c salariul se mrete cu fiecare an de vechime cu 1.8%, pentru cei ce nu
ctig comision i cu 0.9% pe an pentru cei ce beneficiaz de comision. Care este
valoarea total a salariilor n aceast lun pentru angajaii care nu beneficiaz de
comision i pentru angajaii care au comision? 4

1
Se folosete clauza ROLLUP
2
Se folosesc clauzele ROLLUP i GROUPING
3
Se adaug clauza HAVING
4
Se recomand folosirea subinterogrilor scalare
Rezolvarea fiei nr. 1 Fia nr.1

1) SELECT ROUND(AVG(sal)), MAX(sal), MIN(sal), SUM(sal) FROM emp WHERE


job='MANAGER'
2) SELECT MAX(TO_CHAR(hiredate,'day, dd month')),MIN(TO_CHAR(hiredate,'day, dd
month')) FROM emp WHERE TO_CHAR(hiredate,'yyyy')='1982'
3) SELECT MIN(ename), MAX(ename) FROM emp
4) SELECT COUNT(comm) FROM emp WHERE deptno=30
5) SELECT COUNT(DISTINCT deptno) FROM emp
6) SELECT COUNT(DISTINCT job) FROM emp
7) SELECT COUNT(empno) FROM emp WHERE TO_CHAR(hiredate,yyyy)=1981
C
Rezolvarea fiei nr. 2 Fia nr. 2 U
P
1) SELECT job, MAX(sal), MIN(sal), SUM(sal), ROUND(AVG(sal)),MAX(sal)-MIN(sal) R
FROM emp GROUP BY job I
2) SELECT job, COUNT(job) FROM emp GROUP BY job N
3) SELECT COUNT(DISTINCT mgr) FROM emp S
4) SELECT a.empno, MIN(b.sal) FROM emp a, emp b WHERE b.mgr=a.empno AND
a.sal>b.sal GROUP BY a.empno HAVING MIN(b.sal)>1000 ORDER BY MIN(b.sal) DESC
5) SELECT CASE WHEN GROUPING(job)=1 THEN 'TOTAL GENERAL'
WHEN GROUPING(ename)=1 THEN 'TOTAL PENTRU FUNCTIA'
ELSE ename END, job , SUM(sal)
FROM emp GROUP BY ROLLUP(job,ename)
6) SELECT CASE WHEN GROUPING(deptno)=1 THEN 'TOTAL GENERAL'
WHEN GROUPING(ename)=1 THEN 'TOTAL PENTRU DEPARTAMENTUL'
ELSE ename END NUME, deptno , SUM(sal)
FROM emp GROUP BY ROLLUP(deptno,ename)
7) SELECT CASE WHEN GROUPING(deptno)=1 THEN 'TOTAL GENERAL'
WHEN GROUPING(job)=1 THEN 'TOTAL DEPARTAMENT'
WHEN GROUPING(ename)=1 THEN 'TOTAL FUNCTIE '
ELSE ename END , deptno, job, SUM(SAL)
FROM emp GROUP BY ROLLUP(deptno, job, ename)

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