PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Wie verkettet man Zeichenfolgen eines Zeichenfolgenfelds in einer PostgreSQL-Abfrage „Gruppieren nach“?

PostgreSQL 9.0 oder höher:

Modernes Postgres (seit 2010) hat den string_agg(expression, delimiter) Funktion, die genau das tut, wonach der Fragesteller gesucht hat:

SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;

Postgres 9 hat auch die Möglichkeit hinzugefügt, einen ORDER BY anzugeben Klausel in einem Aggregatausdruck; Andernfalls müssen Sie alle Ihre Ergebnisse ordnen oder sich mit einer undefinierten Reihenfolge befassen. Sie können also jetzt schreiben:

SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;

PostgreSQL 8.4.x:

PostgreSQL 8.4 (2009) hat die Aggregatfunktion array_agg(expression) eingeführt die die Werte in einem Array sammelt. Dann array_to_string() kann verwendet werden, um das gewünschte Ergebnis zu liefern:

SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;

PostgreSQL 8.3.x und älter:

Als diese Frage ursprünglich gestellt wurde, gab es keine integrierte Aggregatfunktion zum Verketten von Zeichenfolgen. Die einfachste benutzerdefinierte Implementierung (neben vielen anderen von Vajda Gabo in diesem Mailinglistenbeitrag vorgeschlagen) ist die Verwendung des eingebauten textcat Funktion (die hinter dem || liegt Betreiber):

CREATE AGGREGATE textcat_all(
  basetype    = text,
  sfunc       = textcat,
  stype       = text,
  initcond    = ''
);

Hier ist das CREATE AGGREGATE Dokumentation.

Dies klebt einfach alle Saiten zusammen, ohne Trennzeichen. Um ein ", " dazwischen eingefügt zu bekommen, ohne es am Ende zu haben, möchten Sie vielleicht Ihre eigene Verkettungsfunktion erstellen und sie durch das "textcat" oben ersetzen. Hier ist eine, die ich zusammengestellt und am 8.3.12 getestet habe:

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;

Diese Version gibt ein Komma aus, selbst wenn der Wert in der Zeile null oder leer ist, sodass Sie eine Ausgabe wie diese erhalten:

a, b, c, , e, , g

Wenn Sie es vorziehen, zusätzliche Kommas zu entfernen, um Folgendes auszugeben:

a, b, c, e, g

Fügen Sie dann ein ELSIF hinzu Überprüfen Sie die Funktion wie folgt:

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;