我一直在寻找答案,但没有找到足够接近我所寻找的东西。
我有两张桌子:
CREATE TABLE skill_tree (
ID SERIAL PRIMARY KEY,
NAME TEXT NOT NULL,
DESCRIPTION TEXT NOT NULL
);
和
CREATE TABLE skill (
ID SERIAL PRIMARY KEY,
NAME TEXT NOT NULL,
DESCRIPTION TEXT NOT NULL,
DURATION INTEGER NOT NULL,
COOLDOWN INTEGER NOT NULL,
SKILL_TREE_ID SERIAL REFERENCES skill_tree(id)
);
我正试图从我的postgres db中返回JSON,其结构如此:
[{
"id": 1,
"name": "skill tree 1",
"description": "skill tree description",
"skills": [{
"id": 1,
"name": "skill 1",
"description": "skill 1 desc",
"duration": 10,
"cooldown": 20
}, {
"id": 2,
"name": "skill 2",
"description": "skill 2 desc",
"duration": 20,
"cooldown": 30
}]
}]
我能够从这里得到类似的东西[PostgreSQL and nodejs/pg, return nested JSON,但是除了技能名称之外我找不到任何东西。
答案 0 :(得分:5)
表格skill
应如下所示:
CREATE TABLE skill (
ID SERIAL PRIMARY KEY,
NAME TEXT NOT NULL,
DESCRIPTION TEXT NOT NULL,
DURATION INTEGER NOT NULL,
COOLDOWN INTEGER NOT NULL,
SKILL_TREE_ID INTEGER REFERENCES skill_tree(id) -- cannot be serial!
);
使用jsonb_build_object()
和jsonb_agg()
。请注意,查询与预期对象类似。
select jsonb_pretty(jsonb_agg(js_object)) result
from (
select
jsonb_build_object(
'id', id,
'name', name,
'description', description,
'skills', jsonb_agg(skill)
) js_object
from (
select
t.*,
jsonb_build_object(
'id', s.id,
'name', s.name,
'description', s.description,
'duration', duration,
'cooldown', cooldown
) skill
from skill_tree t
join skill s on s.skill_tree_id = t.id
) s
group by id, name, description
) s;
我用jsonb_pretty()包装了结果以获得一个不错的输出:
result
-------------------------------------------------
[ +
{ +
"id": 1, +
"name": "skill tree 1", +
"skills": [ +
{ +
"id": 1, +
"name": "skill 1", +
"cooldown": 20, +
"duration": 10, +
"description": "skill 1 desc" +
}, +
{ +
"id": 2, +
"name": "skill 2", +
"cooldown": 30, +
"duration": 30, +
"description": "skill 2 desc" +
} +
], +
"description": "skill tree description"+
} +
]
请注意,json对象的元素顺序是未定义的。