sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLはJSON配列として結果セットを返しますか?

    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へのクレジット



    1. SQL SERVER 2016 –実行プランの比較

    2. リストビューでのページネーション

    3. MySqlは、日次、週次、月次、および年次でレコードまたはデータを取得します

    4. SQLite-ORDER BY RAND()