Gruparea rezultatelor unei interogări

Similar documents
Funcţii grup şi clauzele GROUP BY, HAVING. Operatorii ROLLUP şi CUBE.

INTEROGĂRI ÎN SQL SERVER

CERERI SELECT PE O TABELA

Titlul lucrării propuse pentru participarea la concursul pe tema securității informatice

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Metrici LPR interfatare cu Barix Barionet 50 -

Structura și Organizarea Calculatoarelor. Titular: BĂRBULESCU Lucian-Florentin

Subiecte Clasa a VI-a

Versionare - GIT ALIN ZAMFIROIU

CERERI SELECT PE MAI MULTE TABELE

Procesarea Imaginilor

Modalitǎţi de clasificare a datelor cantitative

Capitolul 4 SUBCERERI. F. Radulescu. Curs: Baze de date - Limbajul SQL

2. Setări configurare acces la o cameră web conectată într-un router ZTE H218N sau H298N

[{CYCLE NOCYCLE}] [{CACHE

:= 950; BEGIN DELETE FROM

MS POWER POINT. s.l.dr.ing.ciprian-bogdan Chirila

5.2 Interogări în SQL

Documentaţie Tehnică

GHID DE TERMENI MEDIA

Excel Advanced. Curriculum. Școala Informală de IT. Educație Informală S.A.

Mecanismul de decontare a cererilor de plata

Semnale şi sisteme. Facultatea de Electronică şi Telecomunicaţii Departamentul de Comunicaţii (TC)

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC

Reflexia şi refracţia luminii. Aplicaţii. Valerica Baban

Nume şi Apelativ prenume Adresa Număr telefon Tip cont Dobânda Monetar iniţial final

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

Textul si imaginile din acest document sunt licentiate. Codul sursa din acest document este licentiat. Attribution-NonCommercial-NoDerivs CC BY-NC-ND

Colegiul Național Calistrat Hogaș Piatra-Neamț LIMBAJUL SQL

ARBORI AVL. (denumiti dupa Adelson-Velskii si Landis, 1962)

INFORMAȚII DESPRE PRODUS. FLEXIMARK Stainless steel FCC. Informații Included in FLEXIMARK sample bag (article no. M )

Interogarea (query), este operaţia prin care se obţin datele

Reţele Neuronale Artificiale în MATLAB

Ghid identificare versiune AWP, instalare AWP şi verificare importare certificat în Store-ul de Windows

Subinterogari SELECT salariul FROM angajaţi WHERE nume= Ionescu SELECT nume, prenume FROM angajaţi WHERE salariul>s

Creare baza de data Deschidem aplicaţia Microsoft Access. Lansarea în execuţie a programului se face urmând calea:

Arbori. Figura 1. struct ANOD { int val; ANOD* st; ANOD* dr; }; #include <stdio.h> #include <conio.h> struct ANOD { int val; ANOD* st; ANOD* dr; }

Baza de date: tabele, date. Componentele unei B.D.: tabele, constrangeri, relatii. Entitati ale unei B.D.: formulare, interogari, rapoarte

R O M Â N I A CURTEA CONSTITUŢIONALĂ

Lucrarea de laborator nr. 4

5.1 Definirea datelor în SQL

X-Fit S Manual de utilizare

Proiectarea bazelor de date # 11. PL/SQL Funcții în PL/SQL (partea a II-a) Adrian Runceanu

Proiectarea bazelor de date. PL/SQL Înregistrări și Colecții # 13. Adrian Runceanu

Update firmware aparat foto

Auditul financiar la IMM-uri: de la limitare la oportunitate

9. CURSOARE. Obiective. În acest Capitol, vom învăţa despre: Manipularea cursoarelor. Folosirea Cursor FOR Loops şi Nesting Cursors.

D în această ordine a.î. AB 4 cm, AC 10 cm, BD 15cm

REVISTA NAŢIONALĂ DE INFORMATICĂ APLICATĂ INFO-PRACTIC

MICROSOFT ACCESS 2007 (DE CĂUTAT???)

UNIVERSITATEA DIN CRAIOVA FACULTATEA DE ELECTROMECANICĂ CATEDRA DE ACŢIONĂRI ELECTRICE. Şef lucrări dr. ing. Cătălin CONSTANTINESCU BAZE DE DATE

La fereastra de autentificare trebuie executati urmatorii pasi: 1. Introduceti urmatoarele date: Utilizator: - <numarul dvs de carnet> (ex: "9",

ISBN-13:

PROIECT. La Baze de date. Evidența activității pentru o firmă IT. Îndrumător: ș. l. dr. ing. Mirela Danubianu. Efectuat de: Grigoriev Sergiu gr.

Olimpiad«Estonia, 2003

Capitolul IF.02. Structurarea bazelor de date

The First TST for the JBMO Satu Mare, April 6, 2018

Proceduri de analizã a datelor

Subprograme şi pachete PL/SQL

SGBD Access 2010: Query

earning every day-ahead your trust stepping forward to the future opcom operatorul pie?ei de energie electricã și de gaze naturale din România Opcom

Dispozitive Electronice şi Electronică Analogică Suport curs 02 Metode de analiză a circuitelor electrice. Divizoare rezistive.

Proceduri stocate. Crearea procedurilor stocate. Varianta 1 În Management Studio se dă clic pe New Query ca în imaginea de mai jos: Fig.

APLICAŢIE INFORMATICĂ PENTRU PREGĂTIREA MISIUNILOR DE NIVEL TACTIC

Baze de date distribuite și mobile

Ghid de utilizare a Calculatorului valorii U

Cap.5 Normalizarea relaţiilor

9. Memoria. Procesorul are o memorie cu o arhitectură pe două niveluri pentru memoria de program și de date.

Mods euro truck simulator 2 harta romaniei by elyxir. Mods euro truck simulator 2 harta romaniei by elyxir.zip

UNIVERSITATEA ŞTEFAN CEL MARE SUCEAVA

Preţul mediu de închidere a pieţei [RON/MWh] Cota pieţei [%]

Aspecte controversate în Procedura Insolvenţei şi posibile soluţii

Laborator 2. Definirea tablourilor şi a funcţiilor (în linia de comandă) în Matlab 7.0

În continuare vom prezenta unele dintre problemele de calcul ale numerelor Fibonacci.

Crearea şi gestionarea tabelelor. Definirea constrângerilor de integritate în SQL

Proprietăţi obiectual-relaţionale în standardul SQL prof. dr. ing. Mircea Petrescu

CAIETUL DE SARCINI Organizare evenimente. VS/2014/0442 Euro network supporting innovation for green jobs GREENET

Propuneri pentru teme de licență

Laborator 1. Programare declarativă. Programare logică. Prolog. SWI-Prolog

PROCEDURA PRIVIND DECONTURILE. 2. Domeniu de aplicare Procedura se aplică în cadrul Universităţii Tehnice Cluj-Napoca

F. Radulescu. Curs: Utilizarea bazelor de date, anul IV C5.

Metoda BACKTRACKING. prof. Jiduc Gabriel

Ce este o BAZA DE DATE?

1.1. Noţiuni introductive

Ministerul Educaţiei Naţionale şi Cercetării Ştiinţifice Olimpiada de Tehnologia Informaţiei etapa judeţeană 2 aprilie 2016

2. Setări configurare acces la o cameră web conectată într-un echipament HG8121H cu funcție activă de router

Laborator 5: PROIECTAREA BAZELOR DE DATE CURSORI (partea a II-a)

Metoda de programare BACKTRACKING

Managementul referinţelor cu

1 Vasile Violeta Ion Popescu Avram Maria Câmpuri în tabel

Itemi Sisteme de Operare

Platformă de e-learning și curriculă e-content pentru învățământul superior tehnic

1. Date, informaţii, cunoştinţe Date Informaţii Cunoştinţele

INSTRUMENTE DE MARKETING ÎN PRACTICĂ:

Ce pot face pe hi5? Organizare si facilitati. Pagina de Home

Figura x.1 Ecranul de pornire al mediului de dezvoltare

Macrocomenzi. Figura 1. Personalizarea barei de meniuri. Se va afișa fereastra din figura 2. Figura 2. Includerea tab ului Developer.

CHAMPIONS LEAGUE 2017 SPONSOR:

ADO.NET - note de curs pentru disciplina "Servere de date"

Ghid pentru configurarea şi utilizarea aplicaţiei clicksign Demo

Transcription:

Metode de selecţie a datelor din tabele multiple. Gruparea rezultatelor unei interogări Metode de selecţie a datelor din tabele multiple Obiective După parcurgerea acestei secţiuni, studentul va avea cunoştinţele necesare: scrierii unei expresii SELECT pentru a accesa date din mai multe tabele folosind legături (joncţiuni) de egalitate si nonegalitate; vizualizării datelor care nu îndeplinesc o condiţie de joncţiune folosind condiţii de joncţiune externă; efectuării unei joncţiuni între un tabel şi el însuşi; NO ENAME DEPTNO 7893 KING 10 7698 BLAKE 30 7934 MILLER 10 DEPT DEPTNO DNAME LOC 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 40 OPERATIONS BOSTON NO DEPTNO LOC 7893 10 NEW YORK 7698 30 CHICAGO 7782 10 NEW YORK 7566 20 DALLAS 7654 30 CHICAGO 7499 30 CHICAGO 14 rows selected Există situaţii când trebuie să accesăm date din mai multe tabele. În exemplul de mai sus, rezultatul afişat conţine date din două tabele separate. atributul NO există în tabelul ; atributul DEPTNO există în ambele tabele şi DEPT; atributul LOC există în tabelul DEPT. Pentru a obţine rezultatul dorit trebuie realizată o legătură între tabelele şi DEPT. Definirea joncţiunilor Vom folosi o condiţie de joncţiune ori de câte ori trebuie să accesăm date din mai multe tablele din baza de date. Se poate crea o corespondenţă între liniile unui tabel şi liniile altui tabel pe baza valorilor comune existente în coloanele corespondente, care sunt de obicei chei primare şi străine. Pentru afişarea datelor din două sau mai multe tabele aflate în relaţie se va scrie o simplă condiţie de joncţiune în clauza WHERE: SELECT tabel1.coloana1, tabel1.coloana2, tabel2.coloana3 FROM tabel1, tabel2 WHERE tabel1.coloana1 = tabel2.coloana3; unde: 1

tabel.coloana tabel1.coloana1 = tabel2.coloana2 indică tabelul şi coloana de unde este extrasă data este condiţia care leagă cele două tabele Observaţii: în momentul scrierii unei expresii SELECT care conţine o condiţie de joncţiune, este indicat ca numele coloanelor să fie precedate de numele tabelului de care aparţin; în acest fel este mărită claritatea codului SQL şi se îmbunătăţeşte accesul la baza de date. dacă un acelaşi nume de coloană apare în mai multe tabele, numele coloanei trebuie prefixat cu numele tabelului de care aparţine. pentru a realiza o legătură între n tabele este nevoie de minim n-1 condiţii de joncţiune (e.g. pentru a lega 4 tabele sunt necesare 3 joncţiuni). Această regula s-ar putea să nu se aplice dacă tabelul are o cheie primară formată din mai multe atribute şi astfel este necesară mai mult de o coloană pentru a identifica în mod unic fiecare linie. Produsul Cartezian Atunci când o condiţie de joncţiune este invalidă sau complet omisă, rezultatul este un produs cartezian în care vor fi afişate toate combinaţiile de linii din tabelele implicate. Un produs cartezian tinde să genereze un număr mare de linii, iar rezultatul său este în general nefolositor. De aceea trebuie inclusă întotdeauna o condiţie de joncţiune validă în clauza WHERE, cu excepţia cazului când se doreşte în mod explicit combinarea tuturor liniilor din tabele implicate în relaţie. Exemplul următor afişează numele fiecărui angajat şi numele departamentului în care lucrează din tabelele şi DEPT. Deoarece nu a fost specificată clauza WHERE, toate liniile (14) din tabelul sunt combinate cu toate liniile (4) din tabelul DEPT, generând astfel 56 de linii în tabelul rezultat. SQL> SELECT emp.ename, dept.dname, dept; ENAME DNAME ------ ----------- KING ACCOUNTING BLAKE ACCOUNTING KING RESEARCH BLAKE RESEARCH 56 rows selected. Tipuri de condiţii de joncţiune Principalele tipuri de condiţii de joncţiune sunt: 1. echi-joncţiune; 2. non-echi-joncţiune. Pe lângă acestea mai există şi alte tipuri de condiţii de joncţiune: 3. joncţiune externă; 4. joncţiune între un tabel şi el însuşi. 1. Echi-joncţiuni Pentru a determina numele departamentului unui angajat trebuie comparată valoarea din coloana DEPTNO din tabelul cu valorile DEPTNO din tabelul DEPT. Legătura astfel creată între tabelele şi DEPT este o echi-joncţiune - valorile din coloana DEPTNO din ambele tabele trebuie să coincidă. 2

NO ENAME DEPTNO 7839 KING 10 7698 BLAKE 30 7782 CLARK 10 7566 JONES 20 7654 MARTIN 30 7499 ALLEN 30 7844 TURNER 30 7900 JAMES 30 7521 WARD 30 7902 FORD 20 7369 SMITH 20 14 rows selected. DEPT DEPTNO DNAME LOC 10 ACCOUNTING NEW YORK 10 ACCOUNTING NEW YORK 20 RESEARCH DALLAS 20 RESEARCH DALLAS 20 RESEARCH DALLAS 14 rows selected. Cheie străină Cheie primară SQL> SELECT emp.empno, emp.ename, 2 emp.deptno, dept.deptno, dept.loc 3 FROM emp, dept 4 WHERE emp.deptno=dept.deptno; NO ENAME DEPTNO DEPTNO LOC ----- ----- ------ ------ ------- 7839 KING 10 10 NEW YORK 7698 BLAKE 30 30 CHICAGO 7782 CLARK 10 10 NEW YORK 7566 JONES 20 20 DALLAS 14 rows selected. În exemplul de mai sus: Clauza SELECT specifică numele coloanelor ce vor fi afişate - numele şi numărul angajatului şi numărul departamentului, care sunt coloane în tabelul ; - numărul, numele şi locaţia departamentului sunt coloane în tabelul DEPT. Clauza FROM specifică cele 2 tabele ce conţin informaţiile utile: tabelul şi tabelul DEPT. Clauza WHERE specifică modul în care se va realiza legătura între tabele. Suplimentar condiţiei de joncţiune, clauza WHERE poate conţine şi alte criterii necesare operaţiei de selecţie a datelor. De exemplu, pentru a afişa codul angajatului KING, numele, numărul şi locaţia departamentului este nevoie de o condiţie suplimentară în clauza WHERE. SQL> SELECT emp.empno, emp.ename, 2 dept.deptno, dept.loc 3 FROM emp, dept 4 WHERE emp.deptno= dept.deptno 5 AND INITCAP(emp.ename) = 'King' ; NO ENAME DEPTNO LOC ------ ------ ------- -------- 7839 KING 10 NEW YORK Alias-uri de tabele Calificarea coloanelor cu ajutorul numelui tabelului poate consuma mult timp, mai ales în cazul în care numele tabelului este un şir lung. Pentru simplificarea codului SQL se pot folosi alias-uri de tabele în locul numelor acestora. SQL> SELECT e.empno, e.ename, e.deptno, d.deptno, d.loc e, dept d 3 WHERE e.deptno=d.deptno; Observatii: Alias-urile de tabel pot avea lungimea maximă de 30 caractere; 3

dacă în clauza FROM se introduce un alias pentru tabel, atunci acel alias trebuie să înlocuiască numele tabelului în toată instrucţiunea SELECT; alias-urile de tabel ar trebui sa fie semnificative; alias-ul unui tabel este valid numai pentru SELECT-ul curent. Realizarea unei legături între mai multe tabele CUSTOMER NAME CUSTID JOCKSSPORTS 100 TKB SPORT 101 VOLLYRITE 102 JUST TENNIS 103 K+T SPORTS 105 SHAPE UP 106 WOMENS SPORTS 107 9 rows selected. ORD CUSTID ORDID 100 610 101 611 102 612 103 601 105 602 106 107 21 rows selected. ORDID ITEMID 610 3 611 1 612 1 601 1 602 1 64 rows selected. ITEM Uneori apare necesitatea realizării unei joncţiuni între mai multe tabele. De exemplu, pentru a afişa numele, numărul comenzii, codul articolelor din comandă, total număr articole şi totalul fiecărei comenzi pentru clientul TKB SPORT va trebui să realizăm o legătură între tabelele CUSTOMER, ORD şi ITEM. SQL> SELECT c.name, o.ordid, i.itemid, 2 i.itemtot, o.total 3 FROM customer c, ord o, item i 4 WHERE c.custid = o.custid 5 AND o.ordid = i.ordid 6 AND c.name = 'TKB SPORT'; NAME ORDID ITEMID ITEMTOT TOTAL --------- ----- ------ ------- ------ TKB SPORT 610 3 58 101.4 TKB SPORT 610 1 35 101.4 TKB SPORT 610 2 8.4 101.4 2. Non-echi-joncţiuni NO ENAME SAL 7839 KING 5000 7698 BLAKE 2850 7782 CLARK 2450 7566 JONES 2975 7654 MARTIN 1250 7499 ALLEN 1600 7844 TURNER 1500 7900 JAMES 950 14 rows selected. SALGRADE GRADE LOSAL HISAL 1 700 1200 2 1201 1400 3 1401 2000 4 2001 3000 5 3001 9999 "salariul din tabelul este între salariul minim şi maxim din tabelul SALGRADE" Relaţia dintre tabelul si SALGRADE este o non-echi-joncţiune, în sensul că nici o coloana din tabelul nu corespunde direct unei coloane din tabelul SALGRADE. Legătura dintre cele două tabele este următoarea: coloana SAL din este cuprinsă între coloanele LOSAL şi HISAL din tabelul SALGRADE. Legătura se obţine folosind un operator, altul decât operatorul egal ( = ). 4

SQL> SELECT e.name, e.sal, s.grade e, salgrade s 3 WHERE e.sal BETWEEN s.losal AND s.hisal; ENAME SAL GRADE ------ ---- ------ JAMES 950 1 SMITH 800 1 ADAMS 1100 1 14 rows selected Exemplul de mai sus crează o non-echi-joncţiune pentru a determina gradul de salarizare al unui angajat. Salariul trebuie să fie între (between) limita inferioară (LOSAL) şi cea superioară (HISAL) a unui nivel de salarizare. 3. Joncţiune externă ENAME DEPTNO KING 10 BLAKE 30 CLARK 10 JONES 20 DEPT DEPTNO DNAME 10 ACCOUNTING 30 SALES 10 ACCOUNTING 20 RESEARCH 40 OPERATIONS Nici un angajat în departamentul OPERATIONS Dacă o linie (înregistrare) nu satisface condiţia de joncţiune, acea linie nu va apare în rezultatul interogării. De exemplu, în condiţia de echi-joncţiune a tabelelor şi DEPT, departamentul OPERATIONS nu va apare pentru că nu există nici o persoană care lucrează în acel departament. Liniile lipsă pot fi returnate dacă în condiţia de joncţiune se utilizează operatorul de joncţiune externă. Operatorul este semnul "+" între paranteze - (+) şi este plasat în acea parte a condiţiei de joncţiune corespunzătoare tabelului deficient în informaţii. Acest operator are ca efect crearea uneia sau a mai multor linii nule la care se poate adaugă una sau mai multe linii din tabelul ce conţine informaţiile neselectate. SELECT tabel.coloana1, tabel.coloana2, FROM tabel1, tabel2 WHERE tabel1.coloana1 = tabel2.coloana2(+) ; unde: tabel1.coloana1 = tabel2.coloana2(+) este condiţia care realizează legătura între tabele; este simbolul pentru joncţiune externă; poate fi plasat in oricare parte a clauzei WHERE, dar nu în ambele părţi simultan. Se va plasa operatorul de joncţiune externă după numele coloanei din tabelul deficitar în informaţii. Următorul exemplu afişează toate numerele şi numele departamentelor. Departamentul OPERATIONS, care nu are nici un angajat este de asemenea afişat. SQL> SELECT e.ename, d.deptno, d.dname e, dept d 3 WHERE e.deptno(+) = d.deptno 4 ORDER BY e.deptno ; ENAME DEPTNO DNAME ------ ------ --------- KING 10 ACCOUNTING CLARK 10 ACCOUNTING 40 OPERATIONS 15 rows selected Restricţii în cazul utilizării unei condiţii de joncţiune externă: 5

operatorul de joncţiune externă poate apare numai într-o singură parte a unei expresii - partea care nu deţine informaţia ce nu este returnată de interogare. El returnează acele linii din tabel care nu au corespondent direct în celălalt tabel. o condiţie ce implică operatorul de joncţiune externă nu poate utiliza operatorul IN şi nici nu poate fi legată de o altă condiţie prin operatorul OR. 4. Condiţii de joncţiune a unui tabel cu el însuşi (WORKER) NO ENAME MGR 7839 KING 7698 BLAKE 7839 7782 CLARK 7839 7566 JONES 7839 7654 MARTIN 7698 7499 ALLEN 7698 (MANAGER) NO ENAME 7839 KING 7839 KING 7839 KING 7698 BLAKE 7698 BLAKE "MGR din tabelul WORKER este egal cu NO din tabelul MANAGER" Unele aplicaţii impun realizarea unei joncţiuni între un tabel şi el însuşi. De exemplu, pentru a găsi numele managerului lui Blake va trebui să: - găsim înregistrarea corespunzătoare angajatului Blake în tabelul, inspectând coloana ENAME; - găsim codul managerului lui Blake din coloana MGR. Codul managerului lui Blake este 7839. - găsim numele managerului având codul NO egal cu 7893 în coloana ENAME. Codul angajatului King este 7839. Deci King este managerul lui Blake. Pe parcursul acestui proces am căutat în tabel de două ori. Prima dată pentru a-l găsi pe Blake în coloana ENAME şi pentru a citi valoarea MGR - 7839. A doua oară am căutat în coloana NO valoarea 7839 şi am extras din coloana ENAME valoarea King. SQL> SELECT worker.ename 'works for' man.ename worker, emp man 3 WHERE worker.mgr = man.empno WORKER.ENAME 'WORKSFOR' MANAG -------------------------------- BLAKE works for KING CLARK works for KING JONES works for KING MARTIN works for BLAKE 13 rows selected Exemplul de mai sus crează o legătură între tabelul şi el însuşi. Pentru a simula două tabele în clauza FROM, se folosesc două aliasuri, numite WORKER şi MAN pentru acelaşi tabel. În acest exemplu, clauza WHERE conţine condiţia de joncţiune care înseamnă "pentru care codul managerului unui angajat coincide cu codul de angajat al managerului". 6

Gruparea rezultatelor unei interogări Obiective Prin parcurgerea acestei secţiuni studentul va dobândi cunoştinţele necesare: identificării funcţiilor grup disponibile; descrierii modului de utilizare a funcţiilor grup; grupării datelor folosind clauza GROUP BY; includerii sau excluderii câmpurilor grupate folosind clauza HAVING; Funcţii grup Funcţiile grup operează pe mulţimi de înregistrări şi furnizează un singur rezultat pentru întregul grup. Exemplul de mai jos afişează salariul maxim din tabelul emp. DEPTNO -------- 10 10 10 20 20 20 20 20 30 30 30 30 30 30 SAL -------- 2450 5000 1300 800 1100 3000 3000 2975 1600 2850 1250 950 1500 1250 salariul maxim în tabelul MAX(SAL) --------- 5000 În tabelul următor sunt descrise funcţiile grup ce pot fi utilizate în clauza SELECT. Parametrii impliciţi apar subliniaţi. Funcţie AVG([DISTINCT ALL] n) COUNT({* [DISTINCT ALL] expr}) MAX([DISTINCT ALL]expr) MIN([DISTINCT ALL] expr) STDDEV([DISTINCT ALL] n) SUM([DISTINCT ALL] n) VARIANCE([DISTINCT ALL] n) Descriere Returnează valoarea medie a lui n, ignorând valorile null; Returnează numărul de rânduri selectate, unde expr evaluează altceva decât valori null. Pentru a număra toate rândurile selectate, inclusiv rândurile duplicat şi cele cu valori null, se va folosi * ; Returnează valoarea maximă pentru expr, ignorând valorile null; Returnează valoarea minimă pentru expr, ignorând valorile null; Calculează abaterea standard a lui n, ignorând valorile null; Calculează suma valorilor lui n, ignorând valorile null; Calculează varianţa lui n, ignorând valorile null; 7

Folosirea funcţiilor grup SELECT coloana, functie_grup(coloana) FROM tabel [WHERE conditie] [ORDER BY coloana]; DISTINCT implică luarea în considerare numai a valorilor neduplicat. Argumentul ALL ia în considerare fiecare valoare, inclusiv valorile duplicat; este opţiunea implicită. tipurile de date admise pentru expr sunt: CHAR, VARCHAR2, NUMBER sau DATE. toate grupurile de funcţii, cu excepţia funcţiei COUNT(*) ignoră valorile null. Pentru a înlocui o valoare null cu o altă valoare se poate utiliza funcţia NVL (e.g. funcţia NVL(COMM,0) va returna 0 dacă COMM are valoarea null şi valoarea COMM dacă aceasta e diferită de null). 1. Funcţiile AVG, SUM, MIN şi MAX Funcţiile AVG şi SUM pot fi aplicate doar coloanele ce conţin date numerice, în timp ce funcţiile MIN şi MAX operează asupra oricărui tip de date. Exemplul următor afişează media salariilor lunare, salariul maxim, respectiv minim şi suma salariilor lunare pentru toţi angajaţii cu funcţia SALESMAN. SQL> SELECT AVG(SAL),MAX(sal), 2 MIN(sal),SUM(sal) 3 FROM emp 4 WHERE job LIKE SALES ; AVG(SAL) MAX(SAL) MIN(SAL) SUM(SAL) -------- -------- -------- -------- 1400 1600 1250 5600 Pentru a afişa numele primului, respectiv ultimului angajat din lista ordonată alfabetic a tuturor angajaţilor se va executa următoarea interogare: SQL> SELECT MIN(ename),MAX(ename) ; MIN(ENAME) MAX(ENAME) --------- ---------- ADAMS WARD Notă : Funcţiile AVG, SUM, VARIANCE şi STDDEV pot fi utilizate doar cu tipuri de date numerice. 2. Funcţia COUNT Funcţia COUNT are două formate: - COUNT(*) şi - COUNT(expr) COUNT(*) returnează numărul de rânduri din interogare, inclusiv liniile duplicat şi cele conţinând valori null, în timp ce COUNT(expr) returnează numărul valorilor diferite de null din coloana identificată prin expr. Exemplul de mai jos afişează numărul angajaţilor din departamentul 30. SQL> SELECT COUNT(*) 3 WHERE deptno = 30; COUNT(*) ------- 6 8

Clauza GROUP BY DEPTNO SAL salariul mediu în tabelul ------ ------- scott.emp 10 2450 pentru fiecare departament 10 5000 2916.6667 10 1300 20 800 DEPTNO AVG(SAL) 20 1100 ------ --------- 20 3000 2175 10 2916.6667 20 3000 20 2175 20 2975 30 1566.6667 30 1600 30 2850 30 1250 1566.6667 30 950 30 1500 30 1250 Până acum, toate funcţiile grup au tratat tabelul ca fiind un grup larg de informaţii. Pentru împărţirea tabelului în grupuri mai mici se poate utiliza clauza GROUP BY. SELECT coloana, functie_grup(coloana) FROM tabel [WHERE conditie] [GROUP BY expresie_de_grupare] [ORDER BY coloana]; unde expresie_de_grupare specifică acele coloane ale căror valori determină criteriul de grupare a liniilor. Clauza GROUP BY determină împărţirea rândurilor din tabel în grupuri. În cazul utilizării unei funcţii grup în conjuncţie cu clauza GROUP BY se va returna rezultatul funcţiei grup pentru fiecare grup. Observaţii: dacă se include o funcţie grup într-o clauză SELECT, lista coloanelor individuale (coloanele care nu apar în funcţia grup) trebuie să apară în clauza GROUP BY. În caz contrar se va genera un mesaj de eroare. utilizarea unei clauze WHERE exclude rândurile care nu satisfac condiţia impusă înainte de a se efectua divizarea în grupuri; în clauza GROUP BY trebuie incluse coloane; este interzisă utilizarea unui alias de coloană în clauza GROUP BY; rândurile sunt sortate implicit în ordinea ascendentă a coloanelor incluse în lista GROUP BY. Este posibilă încălcarea acestei reguli folosind clauza ORDER BY. Următorul exemplu afişează numărul fiecărui departament împreună cu media salariilor pe acel departament. Modul de evaluare al instrucţiunii SELECT conţinând o clauză GROUP BY este următorul: - clauza SELECT specifică acele coloane ce urmează să fie afişate: - coloana deptno corespunzătoare numărului departamentului - media salariilor din grupul specificat în clauza GROUP BY 9

- clauza FROM indică tabelul ce trebuie accesat - emp. - clauza WHERE specifică rândurile ce vor fi selectate. Dacă nu există clauză WHERE vor fi luate în considerare toate rândurile. - clauza GROUP BY specifică modul de grupare al rândurilor. Rândurile sunt grupate după numărul departamentului, deci funcţia AVG (aplicată coloanei sal) va calcula media salariilor pentru fiecare departament. SQL> SELECT deptno, AVG(sal) 3 GROUP BY deptno; DEPTNO AVG(SAL) ------ --------- 10 2916.6667 20 2175 30 1566.6667 Notă: Coloana ce apare în clauza GROUP BY nu trebuie să apară obligatoriu în clauza SELECT. De exemplu, instrucţiunea SELECT de mai jos afişează media salariilor pentru fiecare departament, fără să afişeze numărul departamentului respectiv. Este permisă utilizarea unei funcţii grup în clauza ORDER BY. SQL> SELECT AVG(sal) 3 GROUP BY deptno; 4 ORDER BY AVG(sal); DEPTNO AVG(SAL) ------- ---------- 30 1566.6667 20 2175 10 2916.6667 Gruparea după mai multe coloane suma salariilor din tabelul scott.emp pentru fiecare funcţie, grupate după DEPTNO JOB SAL departament ------ -------- ------ 10 MANAGER 2450 10 PRESIDENT 5000 DEPTNO JOB SUM(SAL) 10 CLERK 1300 ------- ------ -------- 20 CLERK 800 10 CLERK 1300 20 CLERK 1100 10 MANAGER 2450 20 ANALYST 3000 10 PRESIDENT 5000 20 ANALYST 3000 20 ANALYST 6000 20 MANAGER 2975 20 CLERK 1900 30 SALESMAN 1600 20 MANAGER 2975 30 MANAGER 2850 30 CLERK 950 30 SALESMAN 1250 30 MANAGER 2850 30 CLERK 950 30 SALESMAN 5600 30 SALESMAN 1500 30 SALESMAN 1250 Unele situaţii cer afişarea unor rezultate de sinteză pentru grupurile din interiorul altor grupuri. Figura de mai sus reprezintă totalul salariilor plătite pentru fiecare funcţie, în cadrul fiecărui departament. Tabelul emp este grupat mai întâi după numărul departamentului şi apoi, în fiecare grup obţinut se realizează o grupare după numele funcţiei. De exemplu, cei doi angajaţi cu funcţia CLERK din departamentul 20 sunt grupaţi împreuna şi este returnat un singur rezultat (salariul total) pentru toţi angajaţii din acest grup. Se pot returna rezultate sinteză pentru grupuri şi subgrupuri prin specificarea mai multor coloane în clauza GROUP BY. Ordinea implicită a rezultatelor afişate poate fi controlată prin ordinea în care apar coloanele în clauza GROUP BY. 10

SQL> SELECT deptno, job,sum(sal) 3 GROUP BY deptno, job; DEPTNO JOB AVG(SAL) ------ ------- --------- 10 CLERK 1300 10 MANAGER 2450 10 PRESIDENT 5000 20 ANALYST 6000 20 CLERK 1900 9 rows selected. Observaţii: clauza WHERE nu poate fi utilizată pentru restricţionarea grupurilor. Dacă se doreşte acest lucru se va utiliza clauza HAVING. SQL> SELECT deptno, AVG(sal) 3 WHERE AVG(sal) > 2000 4 GROUP BY deptno; WHERE AVG(sal)>2000 * ERROR at line 3: ORA-00934: group function is not allowed here Această eroarea poate fi corectată prin folosirea clauzei HAVING pentru a restricţiona grupurile ce vor fi afişate. SQL> SELECT deptno,avg(sal) 3 GROUP BY deptno 4 HAVING AVG(sal)>2000; DEPTNO AVG(SAL) ------ --------- 10 2916.6667 20 2175 Clauza HAVING În acelaşi mod în care clauza WHERE este utilizată pentru a restricţiona rândurile selectate, se poate utiliza clauza HAVING pentru a restricţiona grupuri. Pentru a găsi salariul maxim din fiecare departament, dar la afişare să participe doar departamentele în care salariul maxim este mai mare de $2900 trebuie efectuate următoarele operaţii: 1. se va căuta salariul maxim pentru fiecare departament, grupând înregistrările după numărul departamentului; 2. se vor restricţiona grupurile la acele departamente cu un salariu maxim mai mare de $2900. DEPTNO SAL ------- ------ salariul maxim pe departament 10 2450 mai mare de 2900 $ 10 5000 5000 10 1300 20 800 DEPTNO AVG(SAL) 20 1100 ------ -------- 20 3000 3000 10 5000 20 3000 20 3000 20 2975 30 1600 30 2850 30 1250 30 950 2850 30 1500 30 1250 Pentru a păstra în rezultat doar acele grupuri ce îndeplinesc o condiţie se va utiliza clauza HAVING. SELECT coloana, functie_grup FROM tabel 11

[WHERE conditie ] [GROUP BY expresie_de_grupare] [HAVING conditie_grup] [ORDER BY coloana]; unde conditie_grup specificată. restricţionează grupurile de rânduri la acele grupuri ce satisfac condiţia Serverul Oracle parcurge următorii pasi când întâlneşte o clauză HAVING : - grupează rândurile - aplică funcţia grup fiecărui grup - afişează doar grupurile care îndeplinesc criteriul din clauza HAVING. Exemplul următor afişează numărul departamentului şi salariul maxim pentru acele departamente în care salariul maxim este mai mare de $2900. SQL> SELECT deptno,max(sal) 3 GROUP BY deptno 4 HAVING max(sal)>2900; DEPTNO MAX(SAL) ------ -------- 10 5000 20 3000 Probleme: 1. Scrieţi o interogare care să afişeze numele fiecărui angajat, precum şi numărul şi numele departamentului în care lucrează. 2. Scrieţi o interogare care afişează numele, numele departamentului şi locul departamentului pentru toţi angajaţii ce au dreptul la comision. 3. Afişaţi numele angajatului şi numele departamentului pentru toţi angajaţii al căror nume conţine un caracter A. 4. Scrieţi o interogare care afişează numele, funcţia, numărul departamentului şi numele departamentului pentru toţi angajaţii care lucrează în DALLAS. 5. Afişaţi numele angajaţilor şi codurile lor, împreună cu numele managerilor şi codurile acestora. Redenumiţi coloanele Employee, Emp#, Manager şi Mgr#. 6. Modificaţi interogarea anterioară pentru a afişa toţi angajaţii, inclusiv pe King care nu are manager. 7. Creaţi o interogare care va afişa numele fiecărui angajat, numărul departamentului în care lucrează şi numele tuturor angajaţilor care lucrează în acelaşi departament. Redenumiţi cât mai expresiv coloanele. 8. Afişaţi structura tabelului SALGRADE. Creaţi o interogare care va afişa numele, funcţia, numele departamentului, salariul şi gradul de salarizare pentru toţi angajaţii. 9. Creaţi o interogare care afişează numele şi data angajării pentru lucrătorii angajaţi după data de angajare a lui Blake. 10. Afişaţi toate numele angajaţilor şi datele de angajare împreună cu numele managerilor şi data lor de angajare pentru toţi cei care au fost angajaţi înaintea managerilor lor. Etichetaţi coloanele Employee, Emp, Hiredate, Manager şi Mgr Hiredate. 11. Afişaţi numărul managerilor (pe baza valorilor din coloana mgr) din tabelul emp. Etichetaţi coloana Numar Manageri. 12. Scrieţi o interogare care să afişeze diferenţa dintre salariul cel mai mare şi cel mai mic din tabelul emp. Etichetaţi coloana Diferenţa. 13. Afişaţi numărul fiecărui manager şi salariul celui mai prost plătit subaltern al său. Excludeţi angajaţii ce nu au manager. Excludeţi grupurile care au salariul minim mai mic decât 1000$. Sortaţi rezultatele în ordine descrescătoare după salar. 14. Scrieţi o interogare care să afişeze numele fiecărui departament, localitatea, numărul de angajaţi şi salariul mediu al angajaţilor din acel departament. Etichetaţi coloanele Dname, Loc, Nr Persoane şi Salariu. 12