ehm*_*cky 19 sql arrays postgresql json aggregate-functions
我有下表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
Run Code Online (Sandbox Code Playgroud)
我想查询{ 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"}]
Run Code Online (Sandbox Code Playgroud)
它是否使用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;
Run Code Online (Sandbox Code Playgroud)
哪个回报:
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"}]
Run Code Online (Sandbox Code Playgroud)
value_two
在对象中有一个额外的键,我想摆脱它.我应该使用哪个SQL(Postgres)查询?
Erw*_*ter 50
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;
Run Code Online (Sandbox Code Playgroud)
从可变参数列表构建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;
Run Code Online (Sandbox Code Playgroud)
但是你松散了原始的列名.对已注册的行类型进行强制转换可避免这种情况.(临时表的行类型也用于即席查询.)
CREATE TYPE foo AS (value_three text, value_four text); -- once in the same session
Run Code Online (Sandbox Code Playgroud)
SELECT value_two
, json_agg(row_to_json((value_three, value_four)::foo)) AS value_four
FROM mytable
GROUP BY value_two;
Run Code Online (Sandbox Code Playgroud)
或者使用子选择而不是ROW
表达式.更详细,但没有类型转换:
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;
Run Code Online (Sandbox Code Playgroud)
克雷格的相关答案中有更多解释: