PostgreSQL 9.0 以降:
現代のPostgres(2010年以降)にはstring_agg(expression, delimiter)
、質問者が探していたことを正確に行う機能があります。
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9では、任意の集計式でORDER BY
句を指定する機能も追加されました。そうしないと、すべての結果を並べ替えるか、未定義の順序を処理する必要があります。したがって、次のように記述できます。
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
PostgreSQL 8.4 (2009 年) では、配列内の値を収集する集計関数が導入されました。array_agg(expression)
次にarray_to_string()
、目的の結果を得るために使用できます。
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
PostgreSQL 8.3.x 以前:
この質問が最初に提起されたとき、文字列を連結する組み込みの集計関数はありませんでした。最も単純なカスタム実装 (このメーリング リストの投稿で Vajda Gabo が提案したものなど) は、組み込みtextcat
関数 (||
演算子の背後にあります) を使用することです。
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
これがCREATE AGGREGATE
ドキュメントです。
これは、セパレーターなしで、すべての文字列を単に接着します。「、」を最後に挿入せずに間に挿入するには、独自の連結関数を作成して、上記の「textcat」に置き換えます。これは、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;
このバージョンでは、行の値が null または空の場合でもカンマが出力されるため、次のような出力が得られます。
a, b, c, , e, , g
これを出力するために余分なコンマを削除したい場合:
a, b, c, e, g
ELSIF
次に、次のように関数にチェックを追加します。
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;