sql >> Databáze >  >> RDS >> PostgreSQL

Jak zřetězit řetězce řetězcového pole v dotazu PostgreSQL „seskupit podle“?

PostgreSQL 9.0 nebo novější:

Moderní Postgres (od roku 2010) má string_agg(expression, delimiter) funkce, která udělá přesně to, co tazatel hledal:

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

Postgres 9 také přidal možnost zadat ORDER BY klauzule v jakémkoli agregovaném výrazu; jinak budete muset seřadit všechny své výsledky nebo se vypořádat s nedefinovaným pořadím. Takže teď můžete napsat:

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

PostgreSQL 8.4.x:

PostgreSQL 8.4 (v roce 2009) zavedl agregační funkci array_agg(expression) který shromažďuje hodnoty v poli. Poté array_to_string() lze použít k dosažení požadovaného výsledku:

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

PostgreSQL 8.3.xa starší:

Když byla tato otázka původně položena, neexistovala žádná vestavěná agregační funkce pro zřetězení řetězců. Nejjednodušší vlastní implementací (kromě mnoha dalších navrženou Vajdou Gabo v tomto příspěvku v mailing listu) je použití vestavěného textcat funkce (která se nachází za || operátor):

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

Zde je CREATE AGGREGATE dokumentaci.

To jednoduše slepí všechny struny dohromady, bez oddělovače. Chcete-li mezi ně vložit znak ",", aniž byste jej měli na konci, možná budete chtít vytvořit vlastní funkci zřetězení a nahradit ji výše uvedenou "textcat". Zde je jeden, který jsem dal dohromady a testoval 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;

Tato verze vypíše čárku, i když je hodnota v řádku prázdná nebo prázdná, takže výstup dostanete takto:

a, b, c, , e, , g

Pokud byste pro tento výstup raději odstranili přebytečné čárky:

a, b, c, e, g

Poté přidejte ELSIF zkontrolujte funkci takto:

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. Jak převést unixové časové razítko na hodnotu data/času v SQL Server

  2. MySQL počet položek v klauzuli

  3. Jak importovat soubor DBF na SQL Server

  4. Instalace pg gem; CHYBA:Nepodařilo se vytvořit nativní rozšíření drahokamů