web-dev-qa-db-ja.com

SQLのJSONオブジェクトの配列として返す(Postgres)

次の表MyTableがあります。

_ id │ value_two │ value_three │ value_four 
────┼───────────┼─────────────┼────────────
  1 │ a         │ A           │ AA
  2 │ a         │ A2          │ AA2
  3 │ b         │ A3          │ AA3
  4 │ a         │ A4          │ AA4
  5 │ b         │ A5          │ AA5
_

_{ value_three, value_four }_でグループ化されたオブジェクト_value_two_の配列をクエリしたい。 _value_two_は、結果に単独で存在する必要があります。結果は次のようになります。

_ value_two │                                                                                    value_four                                                                                 
───────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 a         │ [{"value_three":"A","value_four":"AA"}, {"value_three":"A2","value_four":"AA2"}, {"value_three":"A4","value_four":"AA4"}]
 b         │ [{"value_three":"A3","value_four":"AA3"}, {"value_three":"A5","value_four":"AA5"}]
_

json_agg()array_agg()のどちらを使用するかは関係ありません。

しかし、私ができる最善は:

_with MyCTE as ( select value_two, value_three, value_four from MyTable ) 
select value_two, json_agg(row_to_json(MyCTE)) value_four 
from MyCTE 
group by value_two;
_

どちらが戻ります:

_ value_two │                                                                                    value_four                                                                                 
───────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 a         │ [{"value_two":"a","value_three":"A","value_four":"AA"}, {"value_two":"a","value_three":"A2","value_four":"AA2"}, {"value_two":"a","value_three":"A4","value_four":"AA4"}]
 b         │ [{"value_two":"b","value_three":"A3","value_four":"AA3"}, {"value_two":"b","value_three":"A5","value_four":"AA5"}]
_

オブジェクトに追加の_value_two_キーを追加します。これを取り除きます。どのSQL(Postgres)クエリを使用すればよいですか?

20
ehmicky

json_build_object() Postgres 9.4以降

_SELECT value_two, json_agg(json_build_object('value_three', value_three
                                           , 'value_four' , value_four)) AS value_four
FROM   mytable 
GROUP  BY value_two;_

マニュアル:

可変個引数リストからJSONオブジェクトを作成します。慣例により、引数リストは交互のキーと値で構成されます。

すべてのバージョン(Postgres 9.3を含む)

row_to_json()ROW 式を使用すると、トリックを実行できます。

_SELECT value_two
     , json_agg(row_to_json((value_three, value_four))) AS value_four
FROM   mytable
GROUP  BY value_two;
_

ただし、元の列名は失われます。登録された行タイプへのキャストはそれを回避します。 (一時テーブルの行タイプは、アドホッククエリにも使用できます。)

_CREATE TYPE foo AS (value_three text, value_four text);  -- once in the same session
_
_SELECT value_two
     , json_agg(row_to_json((value_three, value_four)::foo)) AS value_four
FROM   mytable
GROUP  BY value_two;_

または、ROW式の代わりにsubselectを使用します。より詳細ですが、型キャストなし:

_SELECT value_two
     , json_agg(row_to_json((SELECT t FROM (SELECT value_three, value_four) t))) AS value_four
FROM   mytable
GROUP  BY value_two;_

クレイグの関連する回答の詳細説明:

db <> fiddle ここ
古いSQLフィドル

50