Werte einer Gruppe zu einer Liste zusammenfassen – GROUP_CONCAT in SQLite
Du willst pro Zeile nicht nur zählen, sondern die Werte selbst sehen – etwa alle Tags eines Beitrags als „PHP, SQL, Tipp" in einer Spalte? Genau dafür gibt es GROUP_CONCAT. Ich zeige dir die Grundform, ein eigenes Trennzeichen und wie du Dubletten sortiert loswirst.
COUNT, SUM, AVG kennt jeder – sie verdichten eine Gruppe zu einer Zahl. Aber manchmal willst du die Werte gar nicht ausrechnen, sondern auflisten: alle Tags eines Beitrags, alle Produkte einer Bestellung, alle Mitglieder eines Teams – schön in einer Spalte. Dafür gibt es in SQLite (und ähnlich in MySQL/PostgreSQL) die Aggregatfunktion GROUP_CONCAT.
Die Grundform
Stell dir eine Tabelle beitrag_tags vor, die zu jedem Beitrag mehrere Tag-Zeilen hat:
SELECT beitrag_id, GROUP_CONCAT(tag) AS tags
FROM beitrag_tags
GROUP BY beitrag_id;Ergebnis – eine Zeile pro Beitrag, alle Tags in einer Spalte:
beitrag_id | tags
-----------+------------------
1 | PHP,SQL,Tipp
2 | Kotlin,ComposeOhne zweites Argument trennt SQLite die Werte mit einem Komma.
Eigenes Trennzeichen
Willst du „PHP, SQL, Tipp" mit Leerzeichen oder | als Trenner, gibst du ihn als zweites Argument mit:
SELECT beitrag_id, GROUP_CONCAT(tag, ', ') AS tags
FROM beitrag_tags
GROUP BY beitrag_id;Dubletten raus und sortiert
Tauchen Werte doppelt auf, hilft DISTINCT. Und mit ORDER BY innerhalb des Aufrufs bestimmst du die Reihenfolge in der Liste:
-- doppelte Tags nur einmal
SELECT beitrag_id, GROUP_CONCAT(DISTINCT tag) AS tags
FROM beitrag_tags
GROUP BY beitrag_id;
-- alphabetisch sortiert (SQLite 3.44+)
SELECT beitrag_id, GROUP_CONCAT(tag ORDER BY tag) AS tags
FROM beitrag_tags
GROUP BY beitrag_id;Kleiner Stolperstein: DISTINCT und ein eigenes Trennzeichen lassen sich in SQLite nicht gleichzeitig im selben Aufruf verwenden – für beides zusammen sortierst du vorher in einer Unterabfrage.
Wofür ich das im Alltag nutze
In meinem CMS spare ich mir damit oft eine zweite Abfrage: Statt Tags in einer Schleife nachzuladen, hole ich sie in einem Rutsch als fertige Liste zur Beitragszeile. Ein Aufruf, alle Tags dabei – weniger Code, weniger Datenbank-Roundtrips.
Wenn du ein Projekt mit einer Datenbank hast, die schnell und sauber abfragt statt in tausend Einzelabfragen zu ertrinken, baue ich dir das – meld dich über bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
Mit Datum und Zeit rechnen in SQLite – strftime und date()
SQLite hat keinen echten Datumstyp – Zeitangaben sind Text oder Zahlen. Mit den eingebauten Funktionen date(), datetime() und strftime() gruppierst du trotzdem nach Monat, rechnest Tage dazu und formatierst sauber. Ich zeige die Muster, die ich ständig brauche.
Fremdschlüssel und ON DELETE CASCADE in SQLite
Ein Fremdschlüssel sorgt dafür, dass keine verwaisten Zeilen entstehen – und mit ON DELETE CASCADE räumt die Datenbank abhängige Daten automatisch mit auf. Wichtig bei SQLite: Du musst die Prüfung pro Verbindung erst einschalten.
CASE WHEN in SQL – Bedingungen direkt in der Abfrage
Mit CASE WHEN baust du Wenn-Dann-Logik direkt in SQL: abgeleitete Spalten, Kategorien aus Zahlen und der Trick, mit dem du in einer Abfrage nach mehreren Kriterien gleichzeitig zählst (bedingte Aggregation).