0% found this document useful (0 votes)
17 views7 pages

Lab 04

1. The document discusses SELECT queries on 3 tables - clients, invoices, and receipts. It covers filtering, new fields, grouping, double grouping using the tables. 2. Examples are provided for filtering on discrete and interval numeric fields, null values, adding a new field, grouping, and combining filters and grouping. 3. Key concepts covered include using WHERE for filtering before grouping and HAVING for filtering after grouping.

Uploaded by

Supremusx
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views7 pages

Lab 04

1. The document discusses SELECT queries on 3 tables - clients, invoices, and receipts. It covers filtering, new fields, grouping, double grouping using the tables. 2. Examples are provided for filtering on discrete and interval numeric fields, null values, adding a new field, grouping, and combining filters and grouping. 3. Key concepts covered include using WHERE for filtering before grouping and HAVING for filtering after grouping.

Uploaded by

Supremusx
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Laborator 4

Instructiunea SELECT. Filtrari, campuri noi, grupari, duble grupari.


Utilizarea a 3 tabele.
1. TABELELE INITIALE
Crearea tabelelor se regaseste in script.
2. INSERARE DE DATE
Popularea tabelelor cu date se face se realizeaza
in ordinea „parinti”  „copii”.
Trebuie respectata ordinea si tipul campurilor.
BEGIN
....
Pentru a adauga datele mai rapid, instructiunile au fost
incadrate intr-o procedura.
Instructiunile se regasesc in script.

END;
/
3. Instructiuni SELECT noi; filtrari utilizand mai multe valori numerice.
- filtrare pe camp numeric VALORI DISCRETE – facturile clientilor 10, 30 SAU 50
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl(+) AND (clienti_DEF.codcl=10 OR clienti_DEF.codcl=30 OR
clienti_DEF.codcl=50)
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE clienti_DEF.codcl=10 OR clienti_DEF.codcl=30 OR clienti_DEF.codcl=50
ORDER BY 2,4;
Pentru a reduce conditia de filtrare, se poate utiliza IN
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl(+) AND clienti_DEF.codcl IN (10,30,50)
ORDER BY 2,4;

SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact


FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE clienti_DEF.codcl IN (10,30,50)
ORDER BY 2,4;
- filtrare pe camp numeric de tip INTERVAL – facturile cu valorile intre 1500 si 2400
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl AND valoare>=1500 AND valoare<=2400
ORDER BY 2,4;
- cerinta de mai sus dar cu utilizarea lui BETWEEN
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl AND valoare BETWEEN 1500 AND 2400
ORDER BY 2,4;
- filtrare pe camp numeric INTERVAL – facturile cu valorile din EXTERIORUL intervalului 1500 .. 2400
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl AND (valoare<1500 OR valoare>2400)
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE valoare<1500 OR valoare>2400
ORDER BY 2,4;
- cerinta de mai sus dar cu utilizarea lui NOT BETWEEN
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl AND valoare NOT BETWEEN 1500 AND 2400
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, datafact
FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE valoare NOT BETWEEN 1500 AND 2400
ORDER BY 2,4;
- filtrare pe valoare NULA – facturile care au sau nu au incasari – se utilizeaza IS NULL sau IS NOT NULL
SELECT facturi_DEF.nrfact, valoare, datafact, codinc, valinc
FROM facturi_DEF,incasari_DEF
WHERE facturi_DEF.nrfact=incasari_DEF.nrfact(+) AND codinc IS NULL
ORDER BY datafact;
SELECT facturi_DEF.nrfact, valoare, datafact, codinc, valinc
FROM facturi_DEF LEFT JOIN incasari_DEF ON facturi_DEF.nrfact=incasari_DEF.nrfact
WHERE codinc IS NOT NULL
ORDER BY 3;
- introducerea in interogarea de mai sus si a informatiilor despre client; informatiile provin din 3 tabele
SELECT clienti_DEF.codcl, dencl, facturi_DEF.nrfact, valoare, datafact, codinc, valinc
FROM clienti_DEF,facturi_DEF,incasari_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl AND facturi_DEF.nrfact=incasari_DEF.nrfact(+) AND codinc IS NULL
ORDER BY dencl;
SELECT clienti_DEF.codcl, dencl, facturi_DEF.nrfact, valoare, datafact, codinc, valinc
FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl LEFT JOIN incasari_DEF ON
facturi_DEF.nrfact=incasari_DEF.nrfact
WHERE codinc IS NULL
ORDER BY dencl;
4. Camp calculat
- sa se adauge in tabelul facturi_DEF un camp nou, cota_tva; se completeaza cu valoarea 0.05 pentru anumite
facturi, 0.1 pentru alte cateva facturi si cu 0.19 pentru restul facturilor. Se foloseste instructiunea CASE; sa
se calculeze apoi, intr-o coloana separata, valoarea cu TVA a facturilor, inclusiv pentru clientul care nu are
facturi; sa se redenumeasca Valoare_cu_TVA

ALTER TABLE facturi_DEF ADD


cota_tva NUMBER(3,2);

UPDATE facturi_DEF
SET cota_tva=
CASE
WHEN nrfact IN (102, 105, 203, 206) THEN 0.05
WHEN nrfact IN (104, 107, 207, 210) THEN 0.10
ELSE 0.19
END;
SELECT * From facturi_DEF;
SELECT nrfact, clienti_DEF.codcl, dencl, valoare, cota_tva, valoare*(1+cota_tva)
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl(+)
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, NVL(valoare,0) AS valnoua, NVL(cota_tva,0) AS cota_noua,
valnoua*(1+cota_noua) AS Valoare_cu_TVA
FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, NVL(valoare,0) AS valnoua, NVL(cota_tva,0) AS cota_noua,
valnoua*(1+NVL(cota_tva,0)) AS Valoare_cu_TVA
FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
ORDER BY 2,4;
SELECT nrfact, clienti_DEF.codcl, dencl, NVL(valoare,0) AS valnoua, NVL(cota_tva,0) AS cota_noua,
NVL(valoare,0)*(1+NVL(cota_tva,0)) AS Valoare_cu_TVA
FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
ORDER BY 2,4;

OBS: seminarul trecut am vazut ca noul nume al unui camp calculat nu poate fi folosit in conditiile de filtrare.
Conform exemplelor de mai sus, noul nume nu poate fi utilizat nici in calculul unui alt camp.
5. Grupari pe camp calculat
- totalul general – NU contine nicio grupare, deci NU are nevoie de optiunea GROUP BY
SELECT SUM(valoare*(1+cota_tva)) AS Total_brut_general
FROM facturi_DEF;
- subtotaluri – presupun obtinerea de valori partiale, pe subgrupuri obtinute prin gruparea in functie de
valorile unuia sau mai multor campuri; de exemplu subtotaluri lunare; in aceasta situatie se poate pune in
discutie si un anumit criteriu de ordonare

SELECT SUM(valoare*(1+cota_tva)) AS Total_brut_lunar


FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact)
ORDER BY EXTRACT(MONTH FROM datafact);

SELECT EXTRACT(MONTH FROM datafact) AS Luna, SUM(valoare*(1+cota_tva)) AS Total_brut_lunar


FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact)
ORDER BY Luna;
OBS: NU este obligatoriu sa apara in SELECT campul (campurile) utilizat (utilizate) in GROUP BY; reciproca insa NU
este adevarata, daca un camp apare in SELECT si nu este camp calculat in urma gruparii (SUM, AVG, MIN, MAX)
atunci el trebuie sa apara OBLIGATORIU si in GROUP BY; in acest ultim caz, un eventual nou nume al campului poate
fi folosit doar in clauza ORDER BY
- alt exemplu de subtotaluri – in functie de client si date din 2 tabele
SELECT clienti_DEF.codcl, dencl, SUM(valoare*(1+cota_tva)) AS Total_brut, COUNT(nrfact) AS Nr_facturi
FROM clienti_DEF LEFT JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY clienti_DEF.codcl, dencl
ORDER BY Nr_facturi DESC, Total_brut DESC;

OBS: daca se doreste ordonare descrescatore la fiecare criteriu, optiunea DESC trebuie precizata la fiecare camp.
- Combinatia grupare – filtrare pe camp calculat– clientii cu total facturi peste 10000

SELECT clienti_DEF.codcl, dencl, SUM(valoare*(1+cota_tva)) AS Total_brut, COUNT(nrfact) AS Nr_facturi


FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY clienti_DEF.codcl, dencl
HAVING SUM(valoare*(1+cota_tva))>=10000
ORDER BY Total_brut DESC;

SELECT clienti_DEF.codcl, dencl, SUM(valoare*(1+cota_tva)) AS Total_brut, COUNT(nrfact) AS Nr_facturi


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY clienti_DEF.codcl, dencl
HAVING SUM(valoare*(1+cota_tva))>=10000
ORDER BY Total_brut DESC;
- Filtrare combinata....clientii cu totalul valoric al facturilor mai mare de 10000..insa doar pentru facturile
emise DUPA data de 01/05/2023.
SELECT clienti_DEF.codcl, dencl, SUM(valoare*(1+cota_tva)) AS Total_brut, COUNT(nrfact) AS Nr_facturi
FROM clienti_DEF,facturi_DEF
WHERE clienti_DEF.codcl=facturi_DEF.codcl(+) AND datafact>=TO_DATE('01/05/2023','dd/mm/yyyy')
GROUP BY clienti_DEF.codcl, dencl
HAVING SUM(valoare*(1+cota_tva))>=10000
ORDER BY Total_brut DESC;

SELECT clienti_DEF.codcl, dencl, SUM(valoare*(1+cota_tva)) AS Total_brut, COUNT(nrfact) AS Nr_facturi


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE datafact>=TO_DATE('01/05/2023','dd/mm/yyyy')
GROUP BY clienti_DEF.codcl, dencl
HAVING SUM(valoare*(1+cota_tva))>=10000
ORDER BY Total_brut DESC;

OBSERVATII
- Filtrarea din clauza WHERE actioneaza inaintea gruparii datelor iar filtrarea din clauza HAVING actioneaza
dupa ce se fac gruparile;
- Se pot utiliza la filtrarea datelor inaintea gruparii, adica in WHERE, atat campuri care apar in SELECT, cat si
campuri care nu apar in SELECT intrucat, din cauza eterogenitatii valorilor lor, ar face ca gruparea sa nu se
realizeze. In exemplul de mai sus se observa ca datafact nu apare intre campurile SELECT, ea fiind utilizata
doar ca si criteriu de filtrare.
6. Grupari, calcule, subinterogari
SELECT MAX(valoare) AS Maxim_facturi, ROUND(AVG(valoare),2) AS Medie_facturi
FROM facturi_DEF;

OBS: NU avem GROUP BY intrucat sunt doar valori calculate pentru intreaga coloana de valori.
- Utilizarea lui MAX

Sa se determine factura cu valoarea cea mai mare si sa se afiseze clientul / clientii care are / au facturi cu
aceasta valoare.

SELECT clienti_DEF.codcl, dencl, MAX(valoare) AS Maxim_facturi


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY clienti_DEF.codcl, dencl;

OBS: maximul general este maximul maximelor fiecarui client. Maximul calculat mai sus se va utiliza in
subinterogare

SELECT clienti_DEF.codcl, dencl, nrfact, valoare AS Maxim


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
WHERE valoare=(SELECT MAX(valoare)
FROM facturi_DEF)
;
- Combinarea a doua functii de grupare...utilizarea lui SUM combinat cu MAX
Sa se determine si sa se afiseze localitatea / localitatile cu cea mai mare valoare a totalului de vanzari.

SELECT localit, SUM(valoare) AS Total_loc


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit;

- Extragerea maximului din coloana TOTAL_LOC;

SELECT localit, MAX(SUM(valoare)) AS Maxim_totaluri_loc


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit;

- intrucat e o dubla grupare, campul localit trebuie sa dispara din SELECT dar trebuie sa ramana in GROUP
BY intrucat gruparea dupa localitate este cea care da totalurile partiale.

SELECT MAX(SUM(valoare)) AS Maxim_totaluri_loc


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit;

Obs: utilizarea tabelei clienti_DEF este necesara doar pentru ca se face gruparea dupa campul localit

- utilizarea celei de-a doua interogari ca subinterogare in prima interogare; intrucat filtrarea se face pe
campul SUM, conditia de filtrare se pune in clauza HAVING

SELECT localit, SUM(valoare) AS Max_t_l


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit
HAVING SUM(valoare)= (SELECT MAX(SUM(valoare))
FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit)
;

OBS: subinterogarea de mai sus poate fi valorificata mai bine daca se doreste afisarea localitatilor care au un volum
de vanzari mai mare de 50% din cel mai mare volum de vanzari, ordonate descrescator in functie de aceste valori.

SELECT localit, SUM(valoare) AS Top_valori


FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit
HAVING SUM(valoare)>=0.5*(SELECT MAX(SUM(valoare))
FROM clienti_DEF INNER JOIN facturi_DEF ON clienti_DEF.codcl=facturi_DEF.codcl
GROUP BY localit)
ORDER BY 2 DESC;
- Combinarea a doua functii de grupare...utilizarea lui SUM combinat cu AVG

Sa se determine si sa se afiseze lunile care au totalul facturilor mai mare decat media acestor totaluri.

- totalul fiecarei luni


SELECT EXTRACT(MONTH FROM datafact) AS Luna, SUM(valoare) AS Total_lunar
FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact);

- Media totalurilor lunare..dubla grupare..

SELECT AVG(SUM(valoare)) AS Media_totaluri_lunare


FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact);
o lunile care au totalul facturilor mai mare decat media acestor totaluri

SELECT EXTRACT(MONTH FROM datafact) AS Luna, SUM(valoare) AS Total_lunar


FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact)
HAVING SUM(valoare)>=(SELECT AVG(SUM(valoare))
FROM facturi_DEF
GROUP BY EXTRACT(MONTH FROM datafact))
ORDER BY 2 DESC;

Obs: intrucat media s-a utilizat doar pentru comparare, nu fost necesara rotunjirea acesteia la doua zecimale.

TEMA:

PORNIND DE LA TOATE EXEMPLELE ILUSTRATE IN SEMINARIILE 2,3,4, PROPUNETI

- ADAUGAREA IN TABELA incasari_DEF A UNUI CAMP NUMIT TRIMESTRU AL CARUI CONTINUT SA FIE
COMPLETAT AUTOMAT CU CUVINTELE primul, al doilea, al treilea, al patrulea IN FUNCTIE DE LUNA DATEI
INCASARII
- 5 INSTRUCTIUNI SELECT CAT MAI INEDITE, FOLOSIND GRUPARI, DUBLE GRUPARI, FILTRARI PENTRU
DIVERSE CAMPURI EXISTENTE SAU CALCULATE, DIN TOATE CELE 3 TABELE.

Astept raspunsurile intr-un document WORD atat instructiunile cat si capturi ale executiei acestora.
Documentul se va incarca pe platforma, in sectiunea dedicata.

Termen: 03.04.2023

You might also like