Documente Academic
Documente Profesional
Documente Cultură
Când facem login pe Facebook, are loc o interogare care verifică dacă există înregistrarea cu
utilizatorul și parola introduse în interfața web; apoi, orice pagină FB este generată din zeci e
interogări, care „scot” conținutul relevant din baza de date (imagini, postări etc)
Când ne uităm pe site de shopping on-line, articolele sunt extrase cu ajutorul interogărilor
din baza de date;
Când facem o plată cu cardul bancar, se interoghează soldul din baza de date a băncii;
Tot cu ajutorul interogărilor, se realizează facturile de mobil sau curent electric ;
În acest capitol vom introduce treptat interogările, folosind baza de date supermarket.accdb, care
are următoarele tabele:
Ne aducem aminte că avem Magazine care emit Bonuri. La rândul lor, Bonurile conțin Produse.
Deoarece un bon poate conține multe produse, iar un produs se poate regăsi pe multe bonuri, avem
tabela de legătură ContinutBon, care înregistrează produsele vândute pe fiecare bon și cantitatea în
care s-a vândut fiecare produs.
Interogările sunt folosite pentru a extrage date din baza de date. Rezultatul unei interogări este
întotdeauna o altă tabelă; de exemplu, o interogare care găsește lista bonurilor emise astăzi este tot
o tabelă care conține detalii despre bonuri.
1. Mai întâi, determinăm ce date trebuie să apară în rezultatul nostru. Mai precis, ne întrebăm
ce coloane trebuie afișate? Și din ce tabele provin aceste coloane?
2. Trebuie să determinăm condițiile pe care trebuie să le îndeplinească coloanele respective.
Atenție: pașii de mai sus trebuie reținuți deoarece se aplică pentru orice interogare!
1. Următoarele coloane: Numele, Pretul – care observăm că provin din tabela Produs;
2. Condiții: Pret < 10
Pentru implementare, din bara principală alegem CREATE Query Design. Apare fereastra cu
tabelele disponibile și specificăm din ce tabelă provin coloanele pe care dorim să le obținem în
cadrul interogării.
În ecranul următor, dăm dublu-clic în tabelă pe coloanele Nume si Pret, pentru a le include ca
rezultat al interogării. Ecranul trebuie să arate astfel:
Observăm următoarele:
În zona (1) se afișează tabelele din care extragem date pentru interogare;
În zona (2) se afișează coloanele ce vor apărea în interogare și condițiile pe care trebuie să le
îndeplinească fiecare înregistrare pentru a fin inclusă în rezultat.
În zona (2) introducem datele ca în imaginea de mai sus:
Acum, să presupunem că dorim să afișăm produsele cu prețul mai mare de 10 RON. Deci trebuie să
edităm interogarea, și navigăm din ecranul curent cu rezultatul interogării, în ecranul anterior, unde
am definit interogarea. Avem mai multe posibilități de navigare:
1. Apăsăm View și alegem Design (Zona 1 din imaginea de mai sus) sau
2. Folosim butoanele din dreapta-jos (Zona 2)
Intrați în modul Design și modificați condiția astfel încât prețul >10 și rulați interogarea. Veți observa
rezultatele aferente. Navigați înapoi în Design și schimbați la varianta inițială, <10.
Vom salva interogarea apăsând butonul de închidere X (1 în imaginea de mai jos), și trecem
denumirea „01 – Produse cu pretul mai mic de 10” (2):
Să se afișeze codurile bonurilor care conțin produse cu prețul mai mic de 10, în cantitate
mai mică de 5 bucăți.
Observăm că interogarea este similară cu cea anterioară; în plus, trebuie să adăugăm coloanele
CodBon și Cantitate care provin din tabela ContinutBon. Așa că vom crea o copie a interogării
anterioare, și vom edita copia pentru a adăuga tabela ContinutBon din care vom prelua coloanele
necesare. Urmăm pașii descriși în continuare:
1. Din lista de obiecte, clic dreapta pe interogarea anterioară (01 – Produse…) apoi Copy
2. Tot în lista de obiecte, clic dreapta și Paste. Modificăm denumirea astfel încât să fie „02 –
Bonuri cu produse cu prețul mai mic de 10 - sub 5 buc”
3. Intrăm în modul de editare al noii interogări, dând clic-dreapta pe noua interogare, apoi
Design View:
1. Prin drag-drop tragem tabela ContinutBon în zona interogării (Zona 1 în imaginea de mai
sus)
2. În tabela ContinutBon dăm dublu-clic pe CodBon și Cantitate pentru a le adăuga în zona de
rezultate;
3. Selectăm coloana CodBon: clic pe zona gri din partea de sus a coloanei (3) și apoi o mutăm în
stânga coloanei Nume;
4. La Cantitate, punem condiția < 5.
Rulam interogarea (butonul ! Run). Este posibil să avem coduri de bon care apar de mai multe ori,
aceasta se întâmplă deoarece un bon poate conține mai multe produse cu pretul mai mic de 10 și în
cantitate mai mică de 5. Pentru a obține valori unice pentru CodBon:
În continuare creați interogări pentru a afișa date conform cerințelor de mai jos. Salvați interogările
folosind nume relevante, sub forma „Nr - Descriere interogare” Observație: Prefixarea interogărilor
cu numere ne asigură că acestea se afișează în ordinea dorită de noi. În plus, este întotdeauna o idee
bună să dăm nume relevante interogărilor, astfel încât colegii care lucrează la același proiect--și
profesorii care evaluează exercițiile—să poată înțelege ușor menirea interogării respective! Și acum,
interogările de rezolvat:
1. Numele magazinului unde s-a emis bonul 24 – folosiți tabelele Magazin și Bon, condiție pe
CodBon;
2. Numerele bonurilor emise în magazinul cu CodMagazin 3;
3. Numele mărfurilor vândute în anul curent--folosiți ca și criteriu:
Year([DataBon]) = Year(Now()).
Observație 1: aduceți-vă aminte că DataBon este de tipul DateTime, ceea ce înseamnă că
stochează anul, luna, ziua, ora, minutul șî secunda. Noi avem nevoie de anul în care a
fost emis bonul, așadar vom folosi funcția Year() pentru extrage anul din data
completă a bonului. Remarcăm că am dat numele coloanei între paranteze pătrate --
[DataBon]. În dreapta semnului egal, extragem anul folosind tot funcția Year(), pe
care o aplicăm însă datei curente, pe care o aflăm cu funcția Now().
Observație 2: de obicei în câmpul Criteria punem un operator de comparație (> ,<, =) urmat
de o valoare. În cazul de față am folosit o egalitate între doi termeni; să reținem
această posibilitate!
4. Listați magazinele unde s-au vândut produse de panificație. Sfat: folosiți criteriul LIKE
"*Paine*". Explicație: dorim să găsim toate produsele al căror nume conține textul „Paine”,
de aceea folosim LIKE și abrevierea *, care înlocuiește orice caracter. Alt exemplu: dacă
dorim produse care încep cu textul „Paine…” vom folosi LIKE "Paine*" – acum caracterul *
este doar după text.
5. Magazinele care au emis bonuri între iulie și septembrie 2013 – datele calendaristice se
izolează folosind caracterul diez, în felul următor: BETWEEN #7/1/2013# AND #9/30/2013#
6. Produse cu prețul cuprins între 5 și 10 RON sau 20 și 30 RON. Explicație: aici avem două
intervale, iar prețul produsului trebuie să se situeze în primul SAU al doile interval. Deci, la
Pret vom folosi criteriul BETWEEN 5 AND 10, și pe linia or: (imediar sub Criteria) adăugăm al
doilea interval.
7. Aflați codurile bonurilor emise in ultimele doua luni. Atenție: acest gen de interogare se
referă la ultimele două luni de la data execuției interogării! Deci trebuie să luăm ca punct de
referință data curentă:
Datele calendaristice pe care le căutăm sunt ulterioare momentului Now() – 2 luni. Totuși,
nu putem pune condiția Month([DataBon]) > Month(Now())-2. Dacă suntem în luna
Februarie (adică luna 2), condiția va evalua dacă Month(DataBon) > 2 – 2
Month(DataBon) > 0, condiție care va fi întotdeauna adevărată, deoarece lunile încep de la 1
și se termină la 12. În consecință toate bonurile vor satisface această condiție și ca urmare
vor fi afișate în lista de rezultate (incluzând bonurile emise după februarie!). Încercați și Dvs.
și convingeți-vă! Soluția este să folosim o funcție care returnează data calendaristică precisă
a momentului cu 2 luni în urmă. Funcția este DateAdd(interval, număr_intervale,
data_inițială) – uitați-vă în help sau Google la descrierea funcției, pentru a înțelege cum
funcționează (important pt. examen). Condiția pe care o folosim pentru data bonului va fi: >
În cuvinte: la data curentă – exprimată prin Now() adaugă -2 intervale de tip „m” – adică
month.
Modificați apoi interogarea pentru a afișa bonurile din ultima lună, și observați că avem mai
puține rezultate.
Observații:
Dacă putem folosi funcții în zona de criterii, rezultă că vom putea folosi și operații matematice. Ne
putem convinge creând o interogare simplă pe tabela Produs, cu condiția Pret > 5+5. Putem
introduce operații oricât de complexe, și putem influența ordinea evaluării prin paranteze.
Operațiile pot fi folosite și pentru a adăuga în rezultatul interogării coloane noi, care nu există în
tabelele originale. De pildă, vrem să afișam produsele și o coloană care să conțină prețul produsului
majorat cu 10%. Creăm o interogare bazată pe tabela Produs, după cum urmează:
PretMajorat: [Pret]*1,1
Cuvântul PretMajorat reprezintă numele noii coloane, și este despărțit de formula propriu-zisă prin
simbolul „:” (două puncte). Putem folosi orice denumiri dorim pentru noua coloană, dar în general
este de preferat să folosim „notația cămilă”, ca și în cazul celorlalte nume de coloane sau variabile.
Observați a treia colană, care afișează rezultatul operației [Pret] * 1.1. Dorim să formatăm această
coloană ca și valută, astfel încât valorile să fie prefixate cu simbolul aferent (În cazul de față „$”, dar
acesta poate fi determinat de setările regionale ale calculatorului). Ne întoarcem în Design View și:
Creați acum o interogare simplă, care afișează codurile tuturor produselor, și rulați-o. Rezultatul
constă într-o singură coloană:
În cazul de mai sus aveam în baza de date 5 produse, și au fost afișate codurile lor. Acum întoarceți-
vă în Design View și dați click pe Totals (1)
Observați că în zona coloanelor (2) apare linia Total, care ne permite să adăugăm funcții de agregare
pentru coloane. Din lista derulantă, alegeți Count. Rulați apoi interogarea. În imaginea de mai jos am
afișat în stânga rezultatul anterior, fără Count, iar în dreapta am afișat rezultatul nou:
Observăm că funcția Count, aplicată coloanei CodProdus, a sintetizat informația returnând o singură
linie cu numărul total de produse. De asemenea, observați că numele coloanei a fost schimbat în
CountOfCodProdus. Salvați acum interogarea folosind o denumire relevantă.
Exercițiu: creați o nouă interogare în care să găsiți prețul mediu al tuturor produselor. Folosim
coloana Pret din tabela Produs și aplicăm funcția de agregare Avg(). În mod similar putem găsi
valorile minime, maxime, deviația standard etc.
CodBon, pe care aplicăm funcția Group, pentru a crea „grupuri” în cadrul rezultatului.
Pentru fiecare CodBon se crează câte un grup. În imaginea de mai sus avem 3 grupuri,
corespunzător celor 3 bonuri diferite (24, 25, și 26).
Cantitate, pe care aplicăm funcția Sum, pentru a însuma numărul de produse din cadrul
fiecărui grup creat pe CodBon. De exemplu, pentru bonul 24, numărul total de produse este
10 + 8 = 18.
Acum creați o nouă interogare bazată pe tabela ConținutBon, cuprinzând câmpurile CodBon și
Cantitate, și activați butonul Totals.
Alegeți Group By pentru CodBon și Sum pentru Cantitate. Rulați interogarea și observăm rezultatul.
În imaginea de mai jos am inclus și rezultatul anterior:
Observăm că pentru fiecare CodBon s-au însumat cantitățile de produse aferente. Salvați
interogarea cu un nume relevant.
Observație: folosiți doar două coloane: una pentru grupare, și cealaltă pentru funcții agregate—
chiar dacă aveți nevoie de mai multe tabele. Începeți prin a determina tabelele și coloanele
necesare. Salvați fiecare interogare folosind nume relevante.
1. Numărul de bonuri emis de fiecare magazin. Sfat: Coloanele de care avem nevoie sunt:
CodMagazin și CodBon, ambele din tabela Bon. grupăm după magazin, numărăm bonurile.
2. Numărul total de produse vândute în fiecare oraș. Sfat: avem nevoie de tabelele magazin și
bon. Orașul provine din tabela magazin. Grupăm după oraș, numărăm CodBon.
3. Numărul total de unități vândut din fiecare produs. Ordonați descrescător după numărul
total de unități, pentru a obține topul celor mai bine vândute produse.
4. Similar cu interogarea de mai sus, ordonați crescător pentru a afla cele mai slab vândute
produse.
5. Numărul total de produse vândute în fiecare lună calendaristică (grupați după
Month([DataBon]))
1.2.2. Agregare cu Criterii
Să revenim acum asupra interogării în care calculam numărul total de produse vândut pe fiecare
bon. Dorim să găsim doar bonurile care conțin mai mult de 20 de produse, deci vom adăuga această
condiție la Criteria:
Acum dorim să modificăm interogarea noastră pentru a găsi pe fiecare bon, numărul total de
produse care au prețul mai mare de 7. Intrăm în DesignView și:
Observăm că acum avem mai puține bonuri, cu un număr mai mic de produse, deoarece prin
îndepărtarea produselor cu preț mai mic decât 7, am redus numărul de produse însumat pe fiecare
bon.
În concluzie: cerințele interogărilor trebuie citite cu atenție, pentru a determina coloanele pe care
punem condițiile. Dacă aceste coloane nu sunt cuprinse în rezultat, trebuie să alegem din funcțiile de
agregare opțiunea Where.
Observație: Ca regulă generală: ORICÂND folosim funcția Group By, trebuie să avem o altă coloană
cu un rezultat agregat (Sum, Count, Average etc) și eventual mai multe coloane cu condiții.
Acum rezolvați următoarele interogări. (Observație: deoarece tabelele conțin—în mod intenționat—
puține date, puteți verifica manual rezultatele interogărilor).
1. Numărul total de bonuri emis după 1 noiembrie 2013. Observație: nu avem grupare! În zona
de rezultat vom avea Count pe CodBon, și adăugăm condiția pentru data calendaristică.
2. Afișați prețul celui mai scump produs. Sfat: fără grupare, folosim Max() din toate produsele.
3. Afișați prețul mediu al produselor care conțin textul „Paine”.
4. Afișați numărul total de produse vândut în fiecare oraș, pentru produsele cu prețul cuprins
între 5 și 10 lei.
5. Afișați magazinul cu cel mai mare număr de produse vândut în luna curentă.
Pentru aceasta, în loc de valoare efectivă „1”, introducem între paranteze pătrate un text, care va fi
afișat la momentul rulării:
Să presupunem că dorim să găsim produsele al căror preț este mai mare decât prețul mediu al
tuturor produselor. Este evident că va trebui să adăugăm un criteriu pentru preț. Dar prețul mediu
este obținut în urma aplicării unei funcții de agregare, iar noi trebuie să comparăm prețul fiecărui
produs cu prețul mediu.
Soluția este să realizăm mai întâi o interogare care calculează prețul mediu al produselor, apoi
interogarea finală, care compară prețul produselor cu prețul mediu obținut în prima interogare.
1. Realizați o interogare pentru a afișa prețul mediu al produselor, ca în imaginea de mai jos.
Schimbați denumirea coloanei astfel încât să fie PretMediu, și pe linia Total alegeți funcția
Avg. Rulați interogarea și observați valoarea rezultatului, precum și numele coloanei:
2. Salvați interogarea, cu numele „Media Preturilor Produselor”.
3. Creați o nouă interogare și alegeți ca surse de date tabela Produs și interogarea Media
Preturilor Produselor (salvată anterior), conform imaginii de mai jos:
Pentru coloana Pret am introdus la Criteria condiția > [PretMediu], care provine din
interogarea anterioară. (Să observăm că între tabelă și interogare nu există nicio relație,
deoarece nu au chei comune). Rulați interogarea, obsevați rezultatul și apoi salvați.
Observație: când realizăm interogări bazate pe alte interogări, este foarte important:
Să comparăm aceleași tipuri de date, adică prețuri cu prețuri, coduri cu coduri etc;
Să fim atenți la numărul de rezultate (linii) pe care le returnează sub-interogarea. În cazul de
mai sus, comparam valoarea prețului cu media prețurilor—adică verificăm dacă o singură
valoare este mai mare decât o altă valoare. Dacă sub-interogarea ar fi returnat mai mult de
o valoare ca rezultat, atunci comparația nu putea fi realizată (deoarece am fi comparat o
valoare cu mai multe valori) și interogarea nu se executa. Pentru a vă convinge, modificați
interogarea cu prețul mediu și scoateți funcția Avg, apoi rulați din nou interogarea
principală.
De acum devine evident că interogările pot fi deosebit de complexe, combinând criterii, grupări, sub-
interogări etc. Vom reveni asupra sub-interogărilor în capitolul despre SQL. Până atunci, nu vă faceți
prea multe griji despre sub-interogări.
Observați că pâinea de casă costă acum 6,05 față de 5,50 înainte de modificare.
Deoarece următoarele cerințe modifică ireversibil datele, creați o copie a bazei de date, închizând-o
și apoi duplicând fișierul.
Realizați interogări pentru următoarele cerințe, pe fișierul de rezervă:
În continuare vom adăuga o înregistrare în tabela Produs, după care o vom șterge.
1. Deschideți tabela Produs și adăugați un nou produs. Notați-vă valoarea lui CodProdus,
deoarece îl vom folosi pentru ștergere.
2. Închideți tabela Produs și creați o nouă interogare, bazată pe tabela Produs. Apăsați din bara
de instrumente butonul Delete și configurați interogarea ca în ecranul de mai jos, astfel încât
să ștergem produsul cu CodProdus = 7.
3. Rulați interogarea. Apare următorul mesaj. Citiți-l cu atenție!
4. Dați clic pe Yes pentru a confirma ștergerea. Mesajul de atenționare dispare și revenim în
ecranul Design View al interogării. Deși nu este aparent, ștergerea s-a realizat. Pentru a vă
convinge, deschideți tabela Produs și observați că produsul a fost șters.
5. Închideți și salvați interogarea.
Acum vom aborda un caz mai complex. Să presupunem că (după ce am efectuat o copie de rezervă a
bazei de date) vrem să ștergem toate bonurile mai vechi de o lună, pentru a preveni umplerea
discului cu date vechi.
4. Rulați interogarea și observați că datele calendaristice ale bonurilor rezultate sunt mai vechi
de o lună. Notați-vă și numărul de înregistrări returnate de această interogare. Apoi
întoarceți-vă în Design View.
5. Acum activați butonul Delete din bara de opțiuni, și rulați interogarea. Apare fereastra de
confirmare, care ne anunță numărul de înregistrări ce vor fi șterse. Acest număr trebuie să
fie același cu numărul de înregistrări returnat la pasul anterior (3).
6. Apăsați Yes pentru a confirma ștergerea. Apare un nouă fereastră:
Dacă s-ar efectua ștergerea, ar rămâne în baza de date vânzări despre care pierdem
informația despre data calendaristică a vânzării (DataBon) și nu vom ști nici în ce magazin au
fost vândute respectivele mărfuri (dacă ștergem bonul pierdem informația despre
CodMagazin).
Access însă refuză să șteargă bonurile din cauza modului în care am definit relația între
tabele:
10. Dați clic-dreapta pe relația dintre tabelele Bon și ConținutBon, apoi Edit Relationship...
Apare ecranul de editare al relației:
Când am creat relația între tabele, am bifat Enforce Referential Integrity. Această opțiune
asigură că pentru o cheie externă, există o valoare corespondentă a cheii primare. În alte
cuvinte, pentru orice înregistrare din ConținutBon există un Bon valid. Ori dacă am fi șters
bonuri, am fi încălcat această regulă. Din acest motiv, Access nu a permis ștergerea. Soluția
este:
11. Bifați opțiunea Cascade Delete Related Records. Această opțiune va șterge înregistrările
aflate în relație cu bonurile. Adică, la ștergerea unui bon se vor șterge automat și
înregistrările corespondente în tabela ConținutBon, astfel încât baza de date să rămână într-
o stare consistentă, fără înregistrări orfane.
12. Apăsați OK pentru a edita relația, apoi închideți ecranul Relationships.
13. Rulați din nou interogarea de ștergere, apoi deschideți tabela Bon pentru a verifica dacă s-au
șters bonurile.
Acum este rândul Dvs:
Ștergeți magazinele din București. Observație: trebuie modificată relația dintre Magazin și
Bon.
Observație: în general, nu ștergem date din sistemele de producție. De regulă datele din sistemele
live se arhivează, fără a se șterge definitiv. În cazul nostru:
Dacă ștergem un produs, îi pierdem prețul și nu vom mai putea calcula corect valoarea
bonurilor
Dacă ștergem un bon, rămân înregistrări „orfane” în ContinutBon, etc.
De aceea, este necesar să planificăm impactul ștergerii înregistrărilor.
Pentru a continua, închideți baza de date pe care ați exersat ștergerile, și deschideți baza de date
care conține toate înregistrările.
În continuare dorim să aflăm cantitatea totală de vânzări pentru fiecare produs, în funcție de zona
geografică (oraș). Observați că avem grupare în funcție de două criterii (Produs, Oraș) și funcția de
agregare Sum(Cantitate). Acest tip de cerință se realizează cu o interogare Crosstab.
Rezultatul arată totalul cantității vândute din fiecare produs, în fiecare oraș. Acum să analizăm
modul în care am definit cele 3 elemente din interogare (antetul liniei, antetul coloanei și valorile din
tabel):
Pentru Row Heading (antet linie) am ales Oras, folosind funcția de agregare Group By.
Pentru Column Heading (antet coloană) am ales Produs, folosind funcția de agregare Group
By.
Pentru Value (valoarea efectivă prezentată în tabel) am ales Cantitate și funcția de agregare
Sum.
Interogările Crosstab sunt deosebit de importante pentru analiza datelor. De obicei, aceste
interogări sunt incluse în rapoartele pentru management și pot folosi ca punct de plecare pentru
fundamentarea deciziilor tactice și strategice, cum ar fi introducerea sau excluderea unei linii de
produse, crearea unei politici de prețuri, extinderea geografică etc.
1. Cantitatea totală de produse vândute în fiecare lună (coloane), în funcție de Oraș (linii).
2. Prețul mediu al produselor vândute în fiecare lună (coloane), pe fiecare magazin (linii).