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;