sql >> Database teknologi >  >> RDS >> PostgreSQL

Hvordan sammenkædes strenge af et strengfelt i en PostgreSQL 'gruppe efter' forespørgsel?

PostgreSQL 9.0 eller nyere:

Modern Postgres (siden 2010) har string_agg(expression, delimiter) funktion, som vil gøre præcis, hvad spørgeren ledte efter:

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

Postgres 9 tilføjede også muligheden for at angive en ORDER BY klausul i ethvert aggregeret udtryk; ellers skal du bestille alle dine resultater eller håndtere en udefineret ordre. Så du kan nu skrive:

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

PostgreSQL 8.4.x:

PostgreSQL 8.4 (i 2009) introducerede aggregatfunktionen array_agg(expression) som samler værdierne i et array. Derefter array_to_string() kan bruges til at give det ønskede resultat:

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

PostgreSQL 8.3.x og ældre:

Da dette spørgsmål oprindeligt blev stillet, var der ingen indbygget aggregatfunktion til at sammenkæde strenge. Den enkleste tilpassede implementering (foreslået af Vajda Gabo i dette postlisteindlæg, blandt mange andre) er at bruge den indbyggede textcat funktion (som ligger bag || operatør):

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

Her er CREATE AGGREGATE dokumentation.

Dette limer simpelthen alle strengene sammen uden separator. For at få et ", " indsat mellem dem uden at have det i slutningen, vil du måske lave din egen sammenkædningsfunktion og erstatte den med "tekstkatten" ovenfor. Her er en jeg sammensatte og testede den 8.3.12:

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;

Denne version vil udskrive et komma, selvom værdien i rækken er null eller tom, så du får output som dette:

a, b, c, , e, , g

Hvis du foretrækker at fjerne ekstra kommaer for at udskrive dette:

a, b, c, e, g

Tilføj derefter en ELSIF tjek til funktionen som denne:

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;


  1. Syntaksfejl på grund af brug af et reserveret ord som et tabel- eller kolonnenavn i MySQL

  2. FLOOR() Eksempler i SQL Server

  3. Sådan får du tiden fra en streng i MySQL

  4. Hvordan kan jeg få kolonnenavne fra en tabel i Oracle?