在我们的数据库中,我们有几个表,它们的构成略有不同。我们想在postgres中构建1个函数,该函数可以使用某种特定的结构从中生成JSON。
这是两个示例表:
CREATE TEMPORARY TABLE tmp_experience( level
character varying , value numeric , score
numeric, mean numeric );
INSERT INTO tmp_experience( level , value ,
score , mean ) VALUES ( 'high' , 0.23 , 30 ,
0.45 ) , ('low' , 0.63 , 45 , 0.56 );
CREATE TEMPORARY TABLE tmp_gender( level
character varying , value numeric ,
percentage numeric );
INSERT INTO tmp_gender( level , value ,
percentage ) VALUES ( 'male' , 2.23 , 35 ) ,
('female' , 1.63 , 65 );
我们要制作以下两个JSON:
{
"high": {
"value": 0.23,
"score": 30,
"mean": 0.45
},
"low": {
"value": 0.63,
"score": 45,
"mean": 0.56
}
}
{
"male": {
"value": 2.23,
"score": 35
},
"female": {
"value": 1.63,
"score": 65
}
}
我们希望Postgres中有一个函数可以做到这一点。我以为这是相对简单的(也许是这样!),但是我根本不知道该怎么做。
答案 0 :(得分:0)
使用聚合函数jsonb_object_agg()
:
select jsonb_object_agg(level, to_jsonb(t)- 'level')
from tmp_experience t;
jsonb_object_agg
---------------------------------------------------------------------------------------------------------
{"low": {"mean": 0.56, "score": 45, "value": 0.63}, "high": {"mean": 0.45, "score": 30, "value": 0.23}}
(1 row)
select jsonb_object_agg(level, to_jsonb(t)- 'level')
from tmp_gender t
jsonb_object_agg
------------------------------------------------------------------------------------------
{"male": {"value": 2.23, "percentage": 35}, "female": {"value": 1.63, "percentage": 65}}
(1 row)
更新
您需要尽可能多的SELECT。您可以将派生表(FROM子句中的子查询)用于嵌套聚合:
-- jsonb_pretty() not necessary, used for readable output
select jsonb_pretty(jsonb_object_agg(country, levels)) as countries
from (
select country, jsonb_object_agg(level, to_jsonb(t)- 'country'- 'level') as levels
from tmp_experience t
group by country
) s
或常用表表达式:
with levels as (
select country, jsonb_object_agg(level, to_jsonb(t)- 'country'- 'level') as levels
from tmp_experience t
group by country
)
select jsonb_pretty(jsonb_object_agg(country, levels)) as countries
from levels;