Postgresql json_array_elements
Posted
技术标签:
【中文标题】Postgresql json_array_elements【英文标题】: 【发布时间】:2017-08-16 13:22:10 【问题描述】:我有 2 张桌子:
表组 - id (bigserial)、name (varchar)、mails (json)
表格邮件 - id (bigserial), name (varchar)
我的分组数据
1, en-mails, ["id" : 1, "id" : 2]
2, fr-mails, ["id" : 3, "id" : 4]
我在邮件中的数据
1, mail1@gmail.com
2, mail2@gmail.com
3, mail3@gmail.com
4, mail4@gmail.com
我的查询:
SELECT tg.name, tm.mail
FROM groups as tg
CROSS JOIN LATERAL json_array_elements (tg.mails :: json) group_mails
LEFT OUTER JOIN mails as tm ON (group_mails ->> 'id') :: BIGINT = tm.c_id
我的结果
Array ( [name] => en-mails [mail] => mail1@gmail.com )
Array ( [name] => en-mails [mail] => mail2@gmail.com )
Array ( [name] => fr-mails [mail] => mail3@gmail.com )
Array ( [name] => fr-mails [mail] => mail4@gmail.com )
我的问题 - 查询如何返回:
Array ( [name] => en-mails [mail] => [mail1@gmail.com, mail2@gmail.com] )
Array ( [name] => fr-mails [mail] => [mail1@gmail.com, mail2@gmail.com] )
提前致谢
【问题讨论】:
【参考方案1】:使用聚合函数array_agg():
SELECT tg.name, array_agg(tm.mail) as mail
FROM groups as tg
CROSS JOIN LATERAL json_array_elements (tg.mails :: json) group_mails
LEFT OUTER JOIN mails as tm ON (group_mails ->> 'id') :: BIGINT = tm.id
GROUP BY 1
name | mail
----------+-----------------------------------
en-mails | mail1@gmail.com,mail2@gmail.com
fr-mails | mail3@gmail.com,mail4@gmail.com
(2 rows)
【讨论】:
我还有一个问题 - 有没有办法对 json 进行分页 (group_mails ->> 'id') - offcet 0 limit count(group_mails)? 我不确定我是否理解这个问题。也许问一个新问题,对问题有更详细的描述。 感谢您的回答。如果在表 'groups' 中,列 'mails' 我有 1000 个 json 元素 - ["id" : 1, "id" : 2] ..... "id" : 1000 ,有吗一种仅选择 100 个并从表“邮件”中获取“名称”的方法,仅针对这 100 个元素? 在实际查询中没有简单的方法可以做到这一点。您必须在子查询中取消嵌套数组,添加排序顺序、偏移量和限制,并将其用作主查询中的派生表。有点复杂。如果我必须这样做,我可能会创建一个提供有限数量数组元素的辅助函数。 PostgreSql : Json Array to Rows using Lateral Join 怎么样?以上是关于Postgresql json_array_elements的主要内容,如果未能解决你的问题,请参考以下文章
集合返回函数(json_array_elements)与表列的连接结果