Aggregationsfunktionen in PostgreSQL selbst schreiben
PostgreSQL bietet einige Aggregationsfunktionen, doch nicht immer sind diese Ausreichend. Doch dies ist kein Problem, denn PostgreSQL bietet ihnen die Möglichkeit eine solche Funktion selbst zu erstellen.
Um eine eigene Aggregationsfunktion zu erstellen, muss eine Funktion in der Datenbank existieren die, die jeweiligen Operationen mit dem jeweiligen Wert durchführt. Im folgenden Beispiel wird eine Funktion erstellen die nichts anderes macht, als eine Zeichenkette mit Hilfe eines angegebenen Trennzeichens mit einer anderen Zeichenkette verbindet.
CREATE OR REPLACE FUNCTION concat_text (IN oldvalue text, IN string text, IN trenner text, OUT ergebnis text)
AS $PROC$
SELECT $3 || $2 || $1
$PROC$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
Ein Aufruf der Funktion concat_text('Apfel', 'Birne', ' ') würde entsprechend "Apfel, Birne" als Ergebnis liefern. Der Aufruf dieser Funktion wird nun innerhalb einer Aggregationsdeclaration definiert. Die Parameterreihenfolge ist fest vorgegeben. PostgreSQL übergibt zuerst den alten Wert aus vorherigen Aufrufen der Funktion, als nächstes den Wert der aktuellen Zeile. Weitere Parameter sind optional, hier übergeben wir das Trennzeichen für unsere Zeichenkette.
DROP AGGREGATE concat (text, text);
CREATE AGGREGATE concat (text, text)
(
SFUNC = concat_text,
STYPE = text,
INITCOND = '',
);
Wenn Sie die Aggregationsfunktion nun mit SELECT concat(Artikelname, ', ') FROM Artikel aufrufen, erhalten Sie als Ergebnis:
, Apfel, Birne, Banane, ...
Das Ergebnis ist schon fast annehmbar, bis auf das Führende Komma. Nun könnte man die Funktion concat_text entsprechend so erweitern das diese mit Hilfe von Plausibilitätesprüfungen nur dann ein Komma schreibt wenn in dem Parameter "oldvalue" auch etwas drin steht.
PostgreSQL bietet aber auch die Möglichkeit eine Funktion anzugeben die aufgerufen werden soll, nachdem alle Datensätze abgearbeitet wurden, diese Funktion kann dann dieses Komma am Anfang entfernen.
CREATE OR REPLACE FUNCTION concat_final (IN oldvalue text, OUT ergebnis text)
AS $PROC$
SELECT substring($1 from 2)
$PROC$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
DROP AGGREGATE concat (text, text);
CREATE AGGREGATE concat (text, text)
(
SFUNC = concat_text,
STYPE = text,
INITCOND = '',
FINALFUNC = concat_final
Der Aufruf der Funktion erfolgt dann beispielsweise so:
SELECT concat(Artikelname, ', ') FROM Artikel;
Viel Spaß bei der Umsetzung Ihres Problems.
Haben Sie Fragen oder Anmerkungen? Ich stehe Ihnen gerne zur Verfügung Ihr Frank Glück