【问题标题】:How do I combine multiple one-to-many results with Postgres json_agg?如何将多个一对多结果与 Postgres json_agg 结合起来?
【发布时间】:2018-04-16 22:49:40
【问题描述】:

函数中有多个 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)

如何重组我的查询,以便只获得第一个示例中正确的“流派”结果以及第二个示例中正确的“故事”结果,而不是像我的实际(第三个)例子?

【问题讨论】:

  • 你为什么突然按这么多东西分组?像以前一样按 ft.id 分组,这行不通?
  • 否;我尝试了各种分组,结果总是一样的,即使只有一个分组。
  • 我相信你可以通过像json_agg(DISTINCT genres) 这样的事情来解决这个问题,这实际上可能是连接的问题,它会让你重复但在我半睡半醒的状态下我不能告诉你什么。

标签: sql json postgresql aggregate-functions


【解决方案1】:

答案如下:

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 2018-10-13
    • 2013-04-19
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2013-11-27
    • 2013-10-21
    相关资源
    最近更新 更多