DISTINCT entfernt doppelte Zeilen
Standardmäßig gibt SELECT jede passende Zeile zurück – inklusive aller Duplikate. Mit DISTINCT weist du SQLite an, Zeilen zusammenzufassen, die in den ausgewählten Spalten identisch sind. So erscheint jede eindeutige Kombination nur ein einziges Mal im Ergebnis.
Aus fünf Zeilen werden drei. SQLite hat sich die Spalte customer angeschaut, die Duplikate aussortiert und pro eindeutigem Wert genau eine Zeile zurückgegeben. Auf die Reihenfolge ist dabei kein Verlass — wenn sie dir wichtig ist, hängst du ein ORDER BY an.
DISTINCT bezieht sich auf die komplette Select-Liste
Hier liegt eine typische Stolperfalle: DISTINCT sucht sich nicht eine einzelne Spalte zum Entfernen von Duplikaten heraus, sondern betrachtet die komplette Zeile über alle Spalten, die du selektierst.
Jedes eindeutige Paar (customer, country) taucht genau einmal auf. Wenn derselbe Kunde mit zwei verschiedenen Ländern vorkommt, siehst du beide Zeilen — für SQLite sind das keine Duplikate.
Eine Syntax wie DISTINCT(customer), die andere Spalten ignoriert, gibt es nicht. Die Klammern sehen verlockend aus, aber SELECT DISTINCT(customer), country wird genauso geparst wie SELECT DISTINCT customer, country — die Klammern gruppieren lediglich einen Ausdruck. Wenn du wirklich pro Kunde nur eine Zeile mit einem ausgewählten Land haben möchtest, ist das ein Fall für GROUP BY zusammen mit einer Aggregatfunktion.
COUNT(DISTINCT spalte) – eindeutige Werte zählen
Eine häufige Frage: Wie viele eindeutige Werte stecken in einer Spalte? COUNT(*) zählt Zeilen, COUNT(col) zählt Werte ungleich NULL, und COUNT(DISTINCT col) zählt die eindeutigen Werte ohne NULL.
Fünf Bestellungen, drei verschiedene Kunden, drei verschiedene Länder. COUNT(DISTINCT ...) ist die nützlichste Aggregat-Variante von DISTINCT – immer dann praktisch, wenn du wissen willst, „wie viele unterschiedliche Werte tatsächlich vorkommen".
Wichtig: SQLite erlaubt innerhalb von COUNT(DISTINCT ...) nur eine einzige Spalte. Um eindeutige Kombinationen aus mehreren Spalten zu zählen, packst du das Ganze in eine Subquery: SELECT COUNT(*) FROM (SELECT DISTINCT a, b FROM t).
Wie DISTINCT mit NULL umgeht
NULL hat in SQL bekanntlich seine Eigenheiten – schließlich ergibt NULL = NULL nicht TRUE, sondern wieder NULL. Bei DISTINCT gilt aber eine Sonderregel: Beim Entfernen von Duplikaten werden alle NULL-Werte als gleich behandelt.
Drei Zeilen kommen zurück: 'ada@example.com', 'dan@example.com' und ein einzelnes NULL. Die drei NULL-Mails wurden zu einer einzigen zusammengefasst. Dieselbe Regel gilt für GROUP BY und für Mengenoperationen wie UNION — gut zu wissen, wenn du dich gerade fragst: „Warum taucht diese NULL-Zeile nur einmal auf statt dreimal?"
DISTINCT läuft vor ORDER BY und LIMIT
Die Klauseln in einem SELECT haben eine feste logische Reihenfolge: FROM → WHERE → GROUP BY → HAVING → SELECT/DISTINCT → ORDER BY → LIMIT. DISTINCT filtert also zuerst die Duplikate raus, danach sortiert ORDER BY das, was übrig bleibt, und am Ende kürzt LIMIT das Ergebnis.
WHERE filtert vier Zeilen heraus, DISTINCT wirft die Dubletten von Boris raus, ORDER BY sortiert alphabetisch und LIMIT liefert nur die ersten beiden zurück. Das einmal Schritt für Schritt durchzugehen lohnt sich – wer sich über die Reihenfolge der Ergebnisse wundert, hat meistens vergessen, welcher Schritt wann passiert.
SQLite DISTINCT vs. GROUP BY
Wenn es nur ums Entfernen von Duplikaten geht, liefern diese beiden Abfragen dieselben Zeilen:
Gleiches Ergebnis. Der Unterschied liegt darin, was du danach machen kannst:
DISTINCTist nur dafür da, "gib mir eindeutige Zeilen" — mehr nicht.GROUP BYist dafür da, Zeilen in Gruppen zu bündeln und pro Gruppe etwas zu berechnen —COUNT(*),SUM(amount),MAX(created_at)und so weiter.
Wenn du also gerade zu DISTINCT greifst und dann merkst, dass du zusätzlich noch eine Summe pro Kunde brauchst, ist das genau das Signal, auf GROUP BY umzusteigen:
Eine Zeile pro Kunde, mit den gewünschten Aggregaten. Mit DISTINCT allein wäre das nicht machbar gewesen – es kennt schlicht keine Möglichkeit, "eine Zeile pro Gruppe plus eine Summe" auszudrücken.
Worauf du achten solltest
- Performance. Damit
DISTINCTDuplikate findet, muss SQLite die Zeilen meist sortieren oder hashen. Bei großen Ergebnismengen hilft ein Index auf den Spalten, die du deduplizierst. Wenn duSELECT DISTINCTüber jede Spalte einer breiten Tabelle laufen lässt, frag dich ehrlich, ob du wirklich alle Spalten brauchst. DISTINCT *kommt selten vor. Erlaubt ist es –SELECT DISTINCT * FROM tdedupliziert komplette Zeilen – aber sobald deine Tabelle einen Primärschlüssel hat, ist ohnehin jede Zeile eindeutig, und das Ganze bringt nichts.- Nicht mit
UNIQUEverwechseln.UNIQUEist ein Constraint auf der Tabelle, der doppelte Werte gar nicht erst hineinlässt.DISTINCTdagegen ist ein Filter zur Abfragezeit, der Duplikate nur im Ergebnis ausblendet. Zwei verschiedene Werkzeuge für zwei verschiedene Aufgaben.
Als Nächstes: CASE-Ausdrücke
Sobald du Ergebniszeilen mit SELECT, WHERE, ORDER BY und DISTINCT formen kannst, geht es im nächsten Schritt um bedingte Logik direkt in der Abfrage. Mit CASE-Ausdrücken kannst du je nach Bedingung unterschiedliche Werte zurückgeben – quasi das SQL-Pendant zu einer if/else-Kette. Genau darum geht es auf der nächsten Seite.
Häufig gestellte Fragen
Wie funktioniert SELECT DISTINCT in SQLite?
SELECT DISTINCT entfernt doppelte Zeilen aus dem Ergebnis. SQLite vergleicht dabei alle Spalten der Select-Liste und behält pro eindeutiger Kombination nur eine Zeile. Angewendet wird DISTINCT nach WHERE und JOIN, aber vor ORDER BY und LIMIT.
Kann ich DISTINCT in SQLite auf mehrere Spalten anwenden?
Ja – DISTINCT bezieht sich grundsätzlich auf die gesamte Select-Liste, nie auf eine einzelne Spalte. SELECT DISTINCT city, country FROM users liefert also jede eindeutige Kombination aus (city, country). Eine Syntax wie DISTINCT(city), die andere Spalten ignoriert, gibt es nicht; wenn du das brauchst, nimm GROUP BY zusammen mit einer Aggregatfunktion.
Wie geht DISTINCT mit NULL-Werten um?
Beim Deduplizieren behandelt DISTINCT NULL als gleich zu anderen NULL-Werten – mehrere Zeilen mit NULL werden also zu einer zusammengefasst. Das weicht vom Verhalten von = in WHERE-Klauseln ab, wo NULL = NULL als unbekannt gilt. Diese Sonderregel greift nur bei DISTINCT, GROUP BY und UNION.
Was ist der Unterschied zwischen DISTINCT und GROUP BY in SQLite?
Wenn es nur ums Entfernen von Duplikaten geht, liefern SELECT DISTINCT col und SELECT col FROM t GROUP BY col exakt dasselbe Ergebnis. Der Unterschied liegt in der Absicht: DISTINCT nimmst du, wenn du einfach nur eindeutige Zeilen willst, GROUP BY dann, wenn du zusätzlich Aggregate wie COUNT(*) oder SUM(amount) pro Gruppe berechnen möchtest.