运行Postgres 9.6。
所以我有这个键/值查找表,它建立了一个巨大的JSON对象的最深子值。给出了这种结构的表格:
CREATE TABLE myschema.file_items
(
id integer NOT NULL DEFAULT nextval('file_items_id_seq'::regclass),
file_id integer NOT NULL,
key character varying[] COLLATE pg_catalog."default" NOT NULL,
value character varying COLLATE pg_catalog."default",
status character varying COLLATE pg_catalog."default",
CONSTRAINT file_items_pkey PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;
ALTER TABLE verification.file_items
OWNER to postgres;
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog1","description"}', 'val1', 'approved');
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog1","cost"}', '100', null);
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog1","window"}', '[-200,500]', 'not verified');
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog2","description"}', 'val2', 'approved');
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog2","cost"}', '200', null);
insert into file_items (file_id, key, value, status)
values (1, '{"cogs","cog2","window"}', '[-300,500]', null);
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget1","description"}', 'wid1', 'approved');
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget1","cost"}', '100', 'approved');
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget1","window"}', '[-200,500]', 'not verified');
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget2","description"}', 'wid2', null);
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget2","cost"}', '300', 'approved');
insert into file_items (file_id, key, value, status)
values (1, '{"widgets","widget2","window"}', '[-1000,700]', null);
我可以查询所有我的齿轮:
select *
from file_items
where 'cogs' = any(key)
我该如何对这个物体进行逆向工程?相反,我想以某种方式生成具有以下格式的json对象:
"cogs": {
"cog1": {
"description": "val1",
"cost":100,
"window":[-200,500]
},
"cog2": {
"description": "val2",
"cost":200,
"window":[-300,500]
}
}
请注意,我故意不想做一组cogs对象。它们是cogs对象的实际属性。这样做是因为我们可以拥有我们不知道所有属性的传入json对象,因此我们利用键/值映射表来动态识别这些属性值是什么(即,我们不&# 39;我们事先知道我们将拥有一个" cog67"对象,或者该对象会附加什么样的属性....)。
由于此查询最终将从Node.js包中触发(' pg'模块...),如果我无法通过查询重新创建json对象,我可能需要在javascript本身做到这一点。只是想知道是否有可能在数据库级别正确构建json对象并返回它,而不是查询一堆行并在服务器端代码中重新构造对象。
任何帮助将不胜感激!谢谢!
答案 0 :(得分:2)
对两个聚合级别使用jsonb_object_agg()
两次(jsonb_pretty()
不必要,用于良好的输出):
select jsonb_pretty(jsonb_build_object(key, jsonb_object_agg(subkey, value)))
from (
select key[1], key[2] as subkey, jsonb_object_agg(key[3], value) as value
from file_items
where 'cogs' = any(key)
group by key[1], key[2]
) s
group by key;
jsonb_pretty
-------------------------------------
{ +
"cogs": { +
"cog1": { +
"cost": "100", +
"window": "[-200,500]",+
"description": "val1" +
}, +
"cog2": { +
"cost": "200", +
"window": "[-300,500]",+
"description": "val2" +
} +
} +
}
(1 row)