Cum funcționează
De ce e nevoie de DISTINCT
Un restaurant poate avea trei comenzi plătite cu cardul. Joncțiunea produce un rând pentru fiecare
comandă, deci numele restaurantului apare de trei ori:
fara DISTINCT cu DISTINCT
Trattoria Bella Trattoria Bella
Sushi Ten Sushi Ten
Sushi Ten La Mama
La Mama ...
DISTINCT elimină rândurile identice din rezultat. Enunțul o cere explicit — „(fără dubluri)" — dar
chiar și fără paranteza aceea, „afișați numele restaurantelor" înseamnă o listă de restaurante, nu o
listă de comenzi.
DISTINCT se aplică pe tot rândul, nu pe o coloană. Detaliul care încurcă cel mai des:
SELECT DISTINCT r.nume, c.idc FROM ... -- DUBLURILE RAMAN
Pentru că perechea (nume, idc) e unică la fiecare comandă — idc e diferit peste tot, deci nu există
două rânduri identice de eliminat. DISTINCT nu e o funcție care se aplică pe r.nume; e o
instrucțiune care spune „aruncă rândurile repetate". Ca să funcționeze, în SELECT trebuie să rămână
doar coloanele după care vrei unicitate.
Varianta echivalentă, fără joncțiune, care evită dublurile prin construcție:
SELECT nume FROM Restaurante
WHERE idr IN (SELECT idr FROM Comenzi WHERE metoda_plata = 'card');
IN verifică apartenența la lista întoarsă de subinterogare. Aici e chiar mai clar: se cere o listă
de restaurante care îndeplinesc o condiție, nu o listă de comenzi.
Același DISTINCT se folosește la
problema #138 (comenzile din luna
curentă) și la #136, acolo în forma
COUNT(DISTINCT ...).
Greșeli frecvente
DISTINCT uitat — numele restaurantelor se repetă de câte ori au comandat clienții. Rezultatul
nu dă eroare, dar nu e lista cerută.
SELECT DISTINCT r.nume, c.idc — dublurile rămân, pentru că DISTINCT lucrează pe rândul
întreg. Cea mai subtilă greșeală de aici.
'Card' cu C mare — în Oracle nu potrivește 'card'. Zero rânduri, fără eroare.
DISTINCT(r.nume) — parantezele sugerează o funcție și induc în eroare; funcționează, dar
DISTINCT nu e funcție. Scrie-l fără paranteze.
GROUP BY r.nume în loc de DISTINCT — dă același rezultat, dar GROUP BY fără agregare e o
grupare fără scop; DISTINCT spune exact ce vrei.