TL; DR
SELECT json_agg(t) FROM t
オブジェクトのJSON配列の場合
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)
FROM t
配列のJSONオブジェクトの場合。
オブジェクトのリスト
このセクションでは、オブジェクトのJSON配列を生成する方法について説明します。各行は単一のオブジェクトに変換されます。結果は次のようになります。
[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]
9.3以降
このjson_agg
関数は、この結果をそのまま使用します。入力をJSONに変換する方法を自動的に判断し、それを配列に集約します。
SELECT json_agg(t) FROM t
のjsonb
(9.4で導入された)バージョンはありませんjson_agg
。行を配列に集約してから変換できます。
SELECT to_jsonb(array_agg(t)) FROM t
またはjson_agg
キャストと組み合わせる:
SELECT json_agg(t)::jsonb FROM t
私のテストでは、最初にそれらを配列に集約する方が少し高速であることを示しています。これはキャストがJSONの結果全体を解析する必要があるためだと思います。
9.2
9.2にはjson_agg
またはto_json
関数がないため、古いものを使用する必要がありますarray_to_json
。
SELECT array_to_json(array_agg(t)) FROM t
オプションrow_to_json
で、クエリに呼び出しを含めることができます。
SELECT array_to_json(array_agg(row_to_json(t))) FROM t
これにより、各行がJSONオブジェクトに変換され、JSONオブジェクトが配列として集約され、配列がJSON配列に変換されます。
2つの間のパフォーマンスの大きな違いを識別することができませんでした。
リストのオブジェクト
このセクションでは、JSONオブジェクトを生成する方法について説明します。各キーはテーブルの列であり、各値は列の値の配列です。結果は次のようになります。
{"a":[1,2,3], "b":["value1","value2","value3"]}
9.5以上
私たちはjson_build_object
機能を活用できます:
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)
FROM t
列を集約して単一の行を作成し、それをオブジェクトに変換することもできます。
SELECT to_json(r)
FROM (
SELECT
json_agg(t.a) AS a,
json_agg(t.b) AS b
FROM t
) r
オブジェクトに目的の名前が付けられるようにするには、配列にエイリアスを設定する必要があります。
どちらがより明確であるかは、意見の問題です。使用する場合json_build_object
関数場合は、読みやすくするために、1つのキーと値のペアを1行に配置することを強くお勧めします。
のarray_agg
代わりに使用することもできますjson_agg
が、私のテストでは、それjson_agg
がわずかに速いことが示されています。
関数のjsonb
バージョンはありませんjson_build_object
。単一の行に集約して変換できます。
SELECT to_jsonb(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
この種の結果に対する他のクエリとは異なり、array_agg
を使用すると、少し高速になるようto_jsonb
です。これは、JSONの結果を解析して検証するオーバーヘッドが原因であると思いますjson_agg
。
または、明示的なキャストを使用できます。
SELECT
json_build_object(
'a', json_agg(t.a),
'b', json_agg(t.b)
)::jsonb
FROM t
to_jsonb
私のテストによると、このバージョンではキャストを回避でき、高速です。繰り返しますが、これは結果の解析と検証のオーバーヘッドによるものだと思います。
9.4および9.3
このjson_build_object
関数は9.5で新しく追加されたため、以前のバージョンではオブジェクトを集計してオブジェクトに変換する必要があります。
SELECT to_json(r)
FROM (
SELECT
json_agg(t.a) AS a,
json_agg(t.b) AS b
FROM t
) r
または
SELECT to_jsonb(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
あなたがしたいかに応じてjson
かjsonb
。
(9.3にはありませんjsonb
。)
9.2
9.2ではto_json
存在しません。使用する必要がありますrow_to_json
:
SELECT row_to_json(r)
FROM (
SELECT
array_agg(t.a) AS a,
array_agg(t.b) AS b
FROM t
) r
ドキュメンテーション
でJSON機能のドキュメント検索JSON関数を。
json_agg
上で集約関数のページ。
設計
パフォーマンスが重要な場合は、私のテストを信頼するのではなく、自分のスキーマとデータに対してクエリをベンチマークするようにしてください。
それが優れたデザインかどうかは、実際のアプリケーションによって異なります。メンテナンス性に関しては特に問題はないと思います。アプリのコードが簡素化され、アプリのその部分で維持する必要が少なくなります。PGが必要な結果をすぐに提供できる場合、私がそれを使用しないと考えることができる唯一の理由はパフォーマンスの考慮です。車輪とすべてを再発明しないでください。
ヌル
集計関数は、通常、NULL
ゼロ行で動作するときに恩恵をもたらします。これが可能である場合、COALESCE
それらを回避するために使用することをお勧めします。いくつかの例:
SELECT COALESCE(json_agg(t), '[]'::json) FROM t
または
SELECT to_jsonb(COALESCE(array_agg(t), ARRAY[]::t[])) FROM t
これを指摘してくれたHannes Landeholmの功績