Cum funcționează
Toate cele zece probleme de la baza de date FIRMA au același tipar: cerința a) atinge un singur
tabel, cerința b) are nevoie de amândouă. Diferența dintre cele două e tot ce trebuie înțeles aici.
a) Un singur tabel
SELECT nume, prenume FROM Angajati; — se cer două coloane, deci se scriu exact acele două. Nu
folosi SELECT *: ar afișa și CNP-ul, și salariul, adică mai mult decât s-a cerut. La corectare,
„afișați numele și prenumele" înseamnă două coloane.
b) Joncțiunea a două tabele
Numele angajatului e în Angajati, data înființării e în Departamente. Nicio interogare pe un
singur tabel nu poate răspunde. Cele două tabele se lipesc prin coloana care apare în ambele —
idd:
INNER JOIN Departamente d ON a.idd = d.idd
a și d sunt aliasuri: prescurtări pentru numele tabelelor, ca să nu scrii
Angajati.nume de fiecare dată. Sunt obligatorii din momentul în care o coloană există în ambele
tabele (aici idd): fără prefix, serverul nu știe la care te referi și dă eroare ambiguous column.
Forma echivalentă, mai veche, care merge la fel în Access și în Oracle:
SELECT a.nume, a.prenume
FROM Angajati a, Departamente d
WHERE a.idd = d.idd AND d.data_infiintare = (...)
Aceeași joncțiune, scrisă cu virgulă și cu condiția în WHERE. Folosește care variantă vrei, dar
condiția de legătură nu se uită niciodată: fără a.idd = d.idd obții produsul cartezian — fiecare
angajat combinat cu fiecare departament, adică 10 × 5 = 50 de rânduri, toate greșite.
„Primul departament înființat” = o subinterogare
„Primul înființat" înseamnă cel cu cea mai mică dată. Data aceea nu e cunoscută în avans, deci se
calculează în interogare:
(SELECT MIN(data_infiintare) FROM Departamente)
Subinterogarea întoarce o singură valoare (2012-09-15), iar WHERE compară cu ea. Pe datele de
test, departamentul e Financiar, cu trei angajați.
Aceeași construcție, cu MAX în loc de MIN, rezolvă cerința „departamentul înființat cel mai
recent" de la problema #125, iar cu
MAX(salariul) — „angajații cu salariul maxim" de la
problema #127. Merită învățată o
dată, se folosește la jumătate din subiecte.
Greșeli frecvente
ORDER BY data_infiintare și se citește primul rând — nu e o interogare, e o citire cu ochii.
Dacă două departamente au fost înființate în aceeași zi, răspunsul corect are două grupuri de
angajați, iar „primul rând" arată doar unul.
- Joncțiune fără condiția de legătură — produs cartezian. Nu dă eroare, dă de cinci ori mai multe
rânduri decât trebuie.
WHERE d.data_infiintare = MIN(data_infiintare) — funcțiile de agregare nu se pot folosi
direct în WHERE. Eroare la execuție. De aceea MIN(...) stă într-o subinterogare.
- Coloană ambiguă —
SELECT idd FROM Angajati a INNER JOIN Departamente d ON a.idd = d.idd dă
eroare, pentru că idd există în ambele tabele. Scrie a.idd.
SELECT * la cerința a) — se cer două coloane, nu toate șapte.
- Punct și virgulă uitat între cele două instrucțiuni.