MrD*_*inB 3 postgresql json nested object
我正在尝试编写一个 Postgres 查询,它将json以特定格式输出我的数据。
JSON 数据结构
{
user_id: 123,
data: {
skills: {
"skill_1": {
"title": "skill_1",
"rating": 4,
"description": 'description text'
},
"skill_2": {
"title": "skill_2",
"rating": 2,
"description": 'description text'
},
"skill_3": {
"title": "skill_3",
"rating": 5,
"description": 'description text'
},
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我最终需要格式化数据的方式:
[
{
user_id: 123,
skill_1: 4,
skill_2: 2,
skill_3: 5,
...
},
{
user_id: 456,
skill_1: 1,
skill_2: 3,
skill_3: 4,
...
}
]
Run Code Online (Sandbox Code Playgroud)
到目前为止,我正在使用如下所示的查询:
SELECT
user_id,
data#>>'{skills, "skill_1", rating}' AS "skill_1",
data#>>'{skills, "skill_2", rating}' AS "skill_2",
data#>>'{skills, "skill_3", rating}' AS "skill_3"
FROM some_table
Run Code Online (Sandbox Code Playgroud)
必须有更好的方法来编写我的查询。有400+行和70+技能。我上面的查询有点疯狂。任何指导或帮助将不胜感激。
一些注意事项:
我将您的测试数据扩展为(注意所有用户周围的数组):
[{
"user_id": 123,
"data": {
"skills": {
"skill_1": {
"title": "skill_1",
"rating": 4,
"description": "description text"
},
"skill_2": {
"title": "skill_2",
"rating": 2,
"description": "description text"
},
"skill_3": {
"title": "skill_3",
"rating": 5,
"description": "description text"
}
}
}
},
{
"user_id": 456,
"data": {
"skills": {
"skill_1": {
"title": "skill_1",
"rating": 1,
"description": "description text"
},
"skill_2": {
"title": "skill_2",
"rating": 3,
"description": "description text"
},
"skill_3": {
"title": "skill_3",
"rating": 4,
"description": "description text"
}
}
}
}]
Run Code Online (Sandbox Code Playgroud)
查询:
SELECT
jsonb_pretty(jsonb_agg(user_id || skills)) -- E
FROM (
SELECT
json_build_object('user_id', user_id)::jsonb as user_id, -- D
json_object_agg(skill_title, skills -> skill_title -> 'rating')::jsonb as skills
FROM (
SELECT
user_id,
json_object_keys(skills) as skill_title, -- C
skills
FROM (
SELECT
(datasets -> 'user_id')::text as user_id,
datasets -> 'data' -> 'skills' as skills -- B
FROM (
SELECT
json_array_elements(json) as datasets -- A
FROM (
SELECT '/* the JSON data; see db<>fiddle */'::json
)s
)s
)s
)s
GROUP BY user_id
ORDER BY user_id
)s
Run Code Online (Sandbox Code Playgroud)
A 使所有数组元素 ( {user_id: '42', data: {...}}) 各占一行
B 第一列安全user_id。对于GROUP BY无法对 JSON 输出进行分组的后者,转换为文本是必要的。对于第二列提取skills用户的数据
C 提取技能标题,将它们用作(D.1)中的键。
D.1skills -> skill_title -> 'rating'从每个技能中提取评分值
D.2json_object_agg将skill_titles 和每个对应的评分值聚合成一个JSON 对象;由user_id
D.3json_build_object再次使 user_id 成为 JSON 对象
E.1user_id || skills将两个json对象聚合为一个
E.2 将jsonb_agg aggregates这些json对象放到一个数组中
E.3jsonb_pretty使结果看起来很漂亮。
结果:
[{
"skill_1": 4,
"skill_2": 2,
"skill_3": 5,
"user_id": "123"
},
{
"skill_1": 1,
"skill_2": 3,
"skill_3": 4,
"skill_4": 42,
"user_id": "456"
}]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3610 次 |
| 最近记录: |