グループクエリ内のフィールドの文字列を連結する方法を探しています。たとえば、次のようなテーブルがあるとします。
ID | 会社ID | 従業員 |
---|---|---|
1 | 1 | アンナ |
2 | 1 | 請求書 |
3 | 2 | キャロル |
4 | 2 | デイブ |
そして、company_id でグループ化して次のような結果を得たいと考えました。
会社ID | 従業員 |
---|---|
1 | アンナ、ビル |
2 | キャロル、デイブ |
MySQLにはこれを実行するための組み込み関数がありますグループ連結
ベストアンサー1
PostgreSQL 9.0 以降:
現代のPostgres(2010年以降)にはstring_agg(expression, delimiter)
質問者が探していたことを正確に実行する関数:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
ORDER BY
Postgres 9では句を指定する機能も追加されましたあらゆる集合表現において; そうでない場合は、すべての結果を順序付けするか、未定義の順序を処理する必要があります。したがって、次のように記述できます。
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
PostgreSQL 8.4.x:
その点に注意してくださいPostgres 8.4のサポートは2014年に終了しましたしたがって、文字列集約よりも重要な理由でアップグレードする必要があると考えられます。
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;