Wróć do: Bazy danych
podstawowy SQLDISTINCTmatura podstawowa z informatyki

DISTINCT – usuwanie duplikatów

Usuwanie powtarzających się wierszy z wyniku zapytania słowem DISTINCT i pułapka porównywania całych wierszy, a nie pojedynczych kolumn.

01

Opis

Wynik zapytania często zawiera powtórzenia. Pytanie „jakie przedmioty są w tabeli ocen" zadane zwykłym SELECT zwróci nazwę przedmiotu tyle razy, ile jest z niego ocen – a nas interesuje sama lista, bez powtórzeń. Od tego jest słowo kluczowe DISTINCT.

DISTINCT stawia się zaraz po SELECT, przed listą kolumn. Baza wykonuje zapytanie normalnie, a na koniec usuwa z wyniku powtarzające się wiersze, zostawiając po jednym egzemplarzu każdego.

Reguła, którą trzeba zapamiętać: DISTINCT porównuje CAŁY wiersz wyniku, nie pojedynczą kolumnę. Dwa wiersze zostaną uznane za takie same tylko wtedy, gdy zgadzają się we wszystkich wypisanych kolumnach. Wystarczy, że w którejkolwiek różnią się choćby jednym znakiem, a oba zostaną w wyniku.

Stąd bierze się najczęstsze nieporozumienie. Zapytanie o same nazwiska z DISTINCT faktycznie zwróci listę unikalnych nazwisk. Ale gdy dopiszesz do listy kolumn imię, DISTINCT zacznie porównywać pary „imię plus nazwisko" – i dwie różne osoby o tym samym nazwisku obie zostaną w wyniku, bo różnią się imieniem. To poprawne działanie, tylko rzadko to, czego się spodziewano.

Odwrotna pułapka jest groźniejsza: DISTINCT nie odróżnia dwóch różnych osób o identycznych danych. Jeśli w tabeli są dwie różne uczennice nazywające się tak samo, DISTINCT skróci je do jednego wiersza – bo widzi wyłącznie wartości, nie rzeczywistość, którą opisują. Dlatego do liczenia osób służy klucz (id), a nie nazwisko.

Jeśli powtórzeń chcesz nie tyle usunąć, ile policzyć, właściwym narzędziem jest GROUP BY – grupowanie bez funkcji agregującej daje zresztą wynik bardzo podobny do DISTINCT.

02

Zapytanie

-- Bez DISTINCT: przedmiot powtarza się tyle razy, ile jest z niego ocen
SELECT przedmiot
FROM oceny
Wynik zapytania
przedmiot
informatyka
matematyka
informatyka
informatyka
matematyka
-- Z DISTINCT: sama lista przedmiotów
SELECT DISTINCT przedmiot
FROM oceny
Wynik zapytania
przedmiot
informatyka
matematyka
-- DISTINCT patrzy na cały wiersz - tu na pary przedmiot + ocena
SELECT DISTINCT przedmiot, ocena
FROM oceny
Wynik zapytania
przedmiotocena
informatyka5
matematyka4
informatyka3
informatyka6
matematyka5

Na maturze

Zanim dopiszesz DISTINCT, sprawdź, które kolumny są w SELECT. Dodanie do listy kolumny o unikalnych wartościach – zwłaszcza id – sprawia, że DISTINCT przestaje cokolwiek usuwać, bo każdy wiersz staje się z definicji niepowtarzalny. To najczęstsza przyczyna sytuacji „napisałem DISTINCT, a duplikaty dalej są".

Uważaj też na polecenia typu „ile jest różnych…". Samo DISTINCT niczego nie liczy – zwraca listę. Do policzenia potrzebna jest funkcja agregująca, a jeśli zadanie pyta o liczbę różnych wartości, warto sprawdzić, czy Twoja baza pozwala policzyć unikaty wprost wewnątrz funkcji zliczającej.

04

Najczęściej zadawane pytania

Czy DISTINCT spowalnia zapytanie?

Tak, bo baza musi porównać wiersze między sobą, żeby wykryć powtórzenia. Przy tabelach z zadania maturalnego jest to niezauważalne, ale to powód, dla którego DISTINCT nie dopisuje się „na wszelki wypadek".

Czy DISTINCT sortuje wynik?

Nie. Wynik bywa uporządkowany przy okazji porównywania wierszy, ale nie jest to obiecane – jeśli kolejność ma znaczenie, dopisz ORDER BY.

Jak DISTINCT traktuje puste wartości?

Wszystkie puste wartości w danej kolumnie uznaje za jedną i zostawia z nich jeden wiersz. To wyjątek od ogólnej zasady, że pustych wartości nie da się ze sobą porównać.

Powiązane zagadnienia