Cum funcționează
a) Tabelul nu are coloana „gen”
Aici e toată dificultatea problemei: structura din enunț nu conține nicio coloană cu sexul
angajatului. Informația există totuși, ascunsă în CNP — și enunțul presupune că știi cum e
construit un CNP.
Prima cifră a CNP-ului codifică simultan genul și secolul nașterii:
| Prima cifră |
Gen |
Perioada nașterii |
1 / 2 |
masculin / feminin |
1900–1999 |
3 / 4 |
masculin / feminin |
1800–1899 |
5 / 6 |
masculin / feminin |
după 2000 |
7 / 8 |
masculin / feminin |
rezident străin |
9 |
— |
persoană străină |
Regula scurtă: cifră impară = masculin, cifră pară = feminin. Se extrage cu SUBSTR:
SUBSTR(cnp, 1, 1) -- din sirul cnp, incepand de la poziția 1, ia 1 caracter
Rezultatul e un șir de un caracter, nu un număr — de aceea se compară cu '1' (între
apostrofuri), nu cu 1. Pe datele de test, condiția prinde și un 5 (angajat născut în 2001), deci
o soluție scrisă doar cu '1' ar pierde un rând.
Aceeași funcție, folosită pentru a scoate anul nașterii din CNP, e la
problema #126.
| Dialect |
Extragere de subșir |
Poziția primului caracter |
| Oracle, SQLite |
SUBSTR(cnp, 1, 1) |
1 |
| Access |
Mid(cnp, 1, 1) sau Left(cnp, 1) |
1 |
| SQL Server |
SUBSTRING(cnp, 1, 1) |
1 |
Alternativa fără funcții de text, dacă preferi: WHERE cnp LIKE '1%' OR cnp LIKE '5%'.
b) „Fondul de salarii” = SUM
Fondul de salarii al unui departament e suma salariilor angajaților lui. SUM adună valorile unei
coloane numerice de pe toate rândurile rămase după WHERE:
SUM(a.salariul) -> 4200 + 3800 + 3600 = 11600
SUM ignoră valorile NULL (nu le tratează ca 0), deci un salariu necompletat nu strică
rezultatul — dar nici nu apare în el.
Greșeli frecvente
- Căutarea unei coloane „gen" sau „sex" — nu există. Informația e în CNP; fără
SUBSTR (sau
LIKE), cerința nu se poate rezolva.
WHERE SUBSTR(cnp, 1, 1) = 1 — se compară un șir cu un număr. Oracle încearcă o conversie
implicită și poate merge; în alte sisteme dă eroare sau zero rânduri. Scrie '1'.
- Doar
'1' și '5' uitat — pierzi toți angajații născuți după 2000. Cei mai tineri angajați,
exact cei care apar în datele de test.
SUBSTR(cnp, 0, 1) — în Oracle, 0 se comportă ca 1; în alte sisteme întoarce șir vid.
Numerotarea caracterelor începe de la 1, nu de la 0 ca la vectori.
COUNT în loc de SUM — „fondul de salarii" e o sumă de bani, nu un număr de angajați.
SUM fără joncțiune — ai adunat salariile din toată firma, nu doar din Comercial. Rezultatul e
un număr plauzibil, deci greșeala trece neobservată.