Return as array of JSON objects in SQL (Postgres)
我有下表
1 2 3 4 5 6 7 | 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 |
我想查询一个按
1 2 3 4 | 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"}] |
不管是使用
但我能做的最好的是:
1 2 3 4 | 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; |
回报:
1 2 3 4 | 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"}] |
在对象中有一个额外的
Postgres 9.4或更新版本中的
1 2 3 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; |
手册:
Builds a JSON object out of a variadic argument list. By convention,
the argument list consists of alternating keys and values.
对于任何版本(包括Postgres 9.3)
带有
1 2 3 4 | SELECT value_two , json_agg(row_to_json((value_three, value_four))) AS value_four FROM mytable GROUP BY value_two; |
但会丢失原始列名称。对已注册行类型的强制转换可避免这种情况。(临时表的行类型也可用于特殊查询。)
1 | CREATE TYPE foo AS (value_three text, value_four text); -- once in the same session |
1 2 3 4 | SELECT value_two , json_agg(row_to_json((value_three, value_four)::foo)) AS value_four FROM mytable GROUP BY value_two; |
或者使用嵌套select而不是
1 2 3 4 | 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; |
克雷格相关答案中的更多解释:
- PostgreSQL 9.2 row_to_json()与嵌套联接
db>小提琴在这里老SQL小提琴。