Wie man Strings in einer PostgreSQL GROUP BY Abfrage verbindet
Bei der Arbeit mit Datenbanken, insbesondere mit PostgreSQL, können Sie auf ein häufiges Szenario stoßen, in dem Sie Strings innerhalb einer Gruppe von Datensätzen verketten müssen. Dies kommt typischerweise ins Spiel, wenn Sie einen Datensatz haben, der mehrere Einträge für eine einzige Kategorie enthält (z. B. Mitarbeiter im gleichen Unternehmen) und diese Einträge in einen einzigen String zur Präsentation oder Analyse sammeln möchten.
In diesem Blogbeitrag wird erklärt, wie Sie die String-Verkettung mit einer GROUP BY
-Abfrage in PostgreSQL erreichen können. Wir werden moderne Lösungen sowie Ansätze für ältere Versionen von PostgreSQL behandeln, um ein umfassendes Verständnis zu ermöglichen.
Das Problem
Nehmen wir beispielsweise die folgende Mitarbeitertabelle:
ID | COMPANY_ID | EMPLOYEE |
---|---|---|
1 | 1 | Anna |
2 | 1 | Bill |
3 | 2 | Carol |
4 | 2 | Dave |
Sie möchten diese Einträge nach COMPANY_ID
gruppieren, sodass die Ausgabe eine Liste von Mitarbeitern anzeigt, die mit jedem Unternehmen verbunden sind. Die gewünschte Ausgabe würde wie folgt aussehen:
COMPANY_ID | EMPLOYEE |
---|---|
1 | Anna, Bill |
2 | Carol, Dave |
Die Lösung
PostgreSQL 9.0 oder Neuer
Wenn Sie PostgreSQL Version 9.0 oder neuer verwenden, können Sie die leistungsstarke eingebaute Funktion string_agg()
verwenden, um Strings innerhalb Ihrer GROUP BY
-Klausel effektiv zu concatenaten.
Hier ist, wie Sie die Abfrage schreiben können:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Mit Sortierung
Darüber hinaus unterstützt PostgreSQL Version 9.0 ORDER BY
innerhalb von Aggregatfunktionen, sodass Sie die Reihenfolge der Mitarbeiter angeben können:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
Dies stellt sicher, dass Ihre Mitarbeiternamen in einer bestimmten Reihenfolge verketten.
PostgreSQL 8.4.x
Wenn Sie weiterhin mit PostgreSQL 8.4 arbeiten, das keine Unterstützung mehr erhält, können Sie die Funktion array_agg()
in Kombination mit array_to_string()
verwenden, um ähnliche Ergebnisse zu erzielen. Hier ist die SQL-Abfrage, die Sie verwenden würden:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x und Älter
Für Benutzer von PostgreSQL 8.3 und früheren Versionen gibt es keine eingebaute Funktion zur direkten Durchführung der String-Verkettung. Die folgende benutzerdefinierte Implementierung kann diese Einschränkung umgehen:
- Erstellen Sie eine neue Aggregatfunktion mit der Funktion
textcat
:
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
- Um Trennzeichen wie
,
zwischen verketteten Strings einzufügen, erstellen Sie eine benutzerdefinierte Funktion:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
Dies wird die Strings entsprechend verbinden.
Wenn Sie zusätzliche Kommas für NULL
oder leere Werte entfernen möchten, hier ist eine verfeinerte Version:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
Fazit
Das Verketten von Strings in PostgreSQL, insbesondere während GROUP BY
-Operationen, ist entscheidend für die Erstellung aussagekräftiger Berichte und Datensätze. Mit der Einführung von Funktionen wie string_agg()
in neueren Versionen ist diese Aufgabe unkompliziert geworden.
Wenn Sie eine ältere Version verwenden, können die hier beschriebenen benutzerdefinierten Aggregationsmethoden ähnliche Ergebnisse erzielen. Überlegen Sie immer, Ihre PostgreSQL-Version zu aktualisieren, um von neueren Funktionen und Sicherheitsverbesserungen zu profitieren.
Viel Spaß beim Abfragen!