函数中的多个json_aggregates
我的 Postgres 数据库的主表与其他表有一对多的关系,每个关系由一个 [*]_references
表连接。我需要一个以 JSON 格式返回其他表结果的结果。我可以联合起来获取我想要的数据:
SELECT ft.id, json_agg(genres) AS genres
FROM ft_references ft
INNER JOIN genre_references gr ON gr.reference_id = ft.id
INNER JOIN genres_catalog genres ON gr.genre_id = genres.id
WHERE ft.id = 2 GROUP BY ft.id;
id | genres
----+--------------------------------------------------
2 | [{"id":1,"name":"Action","other_info":null}, +
| {"id":2,"name":"Adventure","other_info":null}, +
| {"id":5,"name":"Comedy","other_info":null}, +
| {"id":8,"name":"Drama","other_info":null}, +
| {"id":10,"name":"Fantasy","other_info":null}, +
| {"id":13,"name":"Horror","other_info":null}, +
| {"id":25,"name":"War","other_info":null}]
(1 row)
同样是我的第二组结果:
SELECT ft.id, json_agg(tales) AS tales
FROM ft_references ft
INNER JOIN tale_references tr ON tr.reference_id = ft.id
INNER JOIN tale_catalog tales ON tales.id = tr.tale_catalog_id
WHERE ft.id = 2 GROUP BY ft.id;
id | tales
----+---------------------------------------------------------------------------------
2 | [{"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}]
(1 row)
这两个结果都是正确的。然而,当我想将它们放在一起时,突然间我得到了我的类型和故事结果的产物(即:三重结果!):
SELECT ft.id, json_agg(genres) AS genres, json_agg(tale) AS tales
FROM ft_references ft
INNER JOIN genre_references gr ON gr.reference_id = ft.id
INNER JOIN genres_catalog genres ON gr.genre_id = genres.id
INNER JOIN tale_references tr ON tr.reference_id = ft.id
INNER JOIN tale_catalog tale ON tale.id = tr.tale_catalog_id
WHERE ft.id = 2 GROUP BY ft.id, gr.reference_id, tr.reference_id;
id | genres | tales
----+--------------------------------------------------+---------------------------------------------------------------------------------
2 | [{"id":1,"name":"Action","other_info":null}, +| [{"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":1,"name":"Action","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":1,"name":"Action","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":2,"name":"Adventure","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":2,"name":"Adventure","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":2,"name":"Adventure","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":5,"name":"Comedy","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":5,"name":"Comedy","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":5,"name":"Comedy","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":8,"name":"Drama","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":8,"name":"Drama","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":8,"name":"Drama","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":10,"name":"Fantasy","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":10,"name":"Fantasy","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":10,"name":"Fantasy","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":13,"name":"Horror","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":13,"name":"Horror","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":13,"name":"Horror","other_info":null}, +| {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}, +
| {"id":25,"name":"War","other_info":null}, +| {"id":82,"tale_id":"570","tale_type":"Pied Piper","other_info":null}, +
| {"id":25,"name":"War","other_info":null}, +| {"id":39,"tale_id":"327A","tale_type":"Hansel and Gretel","other_info":null}, +
| {"id":25,"name":"War","other_info":null}] | {"id":8,"tale_id":"124","tale_type":"The Three Brothers","other_info":null}]
(1 row)
如何重组我的查询,以便我只获得第一个示例中的正确“流派”结果,以及第二个示例中的正确“故事”结果,而不是像我的实际(第三个)例子?
最佳答案
答案如下:
SELECT ft.id,
json_agg(DISTINCT genres.*) AS genres,
json_agg(DISTINCT tale.*) AS tales
FROM ft_references ft
JOIN genre_references gr ON gr.reference_id = ft.id
JOIN genres_catalog genres ON genres.id = gr.genre_id
JOIN tale_references tr ON tr.reference_id = ft.id
JOIN tale_catalog tale ON tale.id = tr.tale_catalog_id
WHERE ft.id = 2 GROUP BY ft.id;
关于sql - 如何将多个一对多结果与 Postgres json_agg 结合起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49867368/