次の表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)クエリを使用すればよいですか?
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オブジェクトを作成します。慣例により、引数リストは交互のキーと値で構成されます。
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;
_
クレイグの関連する回答の詳細説明: