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配列に変換されます。
両者のパフォーマンスに大きな違いは見分けられませんでした。
リストのオブジェクト
このセクションでは、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_agg
のJSON結果のオーバーヘッド解析と検証が原因であると思われます。 。
または、明示的なキャストを使用できます:
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
これを指摘してくれたHannesLandeholmへのクレジット