【问题标题】:How to get count or records returned from json_agg() query?如何获取从 json_agg() 查询返回的计数或记录?
【发布时间】:2020-12-18 05:11:04
【问题描述】:

我正在动态构建一些看起来像这样的查询

select array_to_json(array_agg(t)) from (
select 
a.field_1,
a.field_2,
jsonb_agg(distinct jsonb_build_object('id',g.id,'data',g.fullname)) as field_4,
jsonb_agg(distinct jsonb_build_object('id',i.optionid,'data',i.option)) as field_9,
jsonb_agg(distinct jsonb_build_object('id',c.id,'data',c.fullname)) as field_6,
jsonb_agg(distinct jsonb_build_object('id',k.id,'data',k.fullname)) as field_8,
jsonb_agg(distinct jsonb_build_object('id',m.id,'data',m.field_20)) as field_21,
l.field_5,
jsonb_agg(distinct jsonb_build_object('id',e.optionid,'data',e.option,'attributes',e.attributes)) as field_23,
n.data as field_13,
jsonb_agg(distinct jsonb_build_object('id',bb.id,'data',bb.fullname)) as field_12

from schema_1.tbl_342 a
left join schema_1.tbl_342_to_tbl_329_field_10 b on a.id=b.tbl_342_id
left join schema_1.tbl_329_customid c on b.tbl_329_id=c.id
left join schema_1.tbl_329 m on m.id=b.tbl_329_id
left join schema_1.tbl_329_field_23_join d on c.id=d.id
left join schema_1.tbl_329_field_23 e on d.optionid = e.optionid
left join schema_1.tbl_342_to_tbl_312_field_4 f on a.id=f.tbl_342_id
left join schema_1.tbl_312_customid g on f.tbl_312_id = g.id
left join schema_1.tbl_342_field_9_join h on h.id=a.id
left join schema_1.tbl_342_field_9 i on i.optionid=h.optionid
left join schema_1.tbl_343_to_tbl_342_field_6 j on j.tbl_342_id=a.id
left join schema_1.tbl_343_customid k on j.tbl_343_id=k.id
left join schema_1.tbl_343 l on l.id=j.tbl_343_id
left join schema_1.tbl_342_field_13_max n on n.id=a.id
group by a.field_1,a.field_2,l.field_5,m.field_23,n.data
) t

输出示例如下

[{"field_1":"Billy","field_2":null,"field_4":[{"id": 4, "data": "Senior Javascript Engineer"}, {"id": 5, "data": "Recruiter"}],"field_9":[{"id": 1, "data": "Blue"}],"field_6":[{"id": 32, "data": "Nancy - 32"}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": 32, "data": "ggñ@cnn.com"}],"field_5":null,"field_23":[{"id": 5, "data": "Expert", "attributes": {"text": "#FFFFFF", "color": "#448AFF"}}],"field_13":"Expert"},{"field_1":"Jackson","field_2":null,"field_4":[{"id": 2, "data": "Marketing Manager M1004"}, {"id": 4, "data": "Senior Javascript Engineer"}, {"id": 5, "data": "Recruiter"}],"field_9":[{"id": 3, "data": "Red"}],"field_6":[{"id": 36, "data": ",Mike - 36"}],"field_8":[{"id": 2, "data": "Henry"}],"field_21":[{"id": 36, "data": "PtereSwanson@gmail.com"}],"field_5":"CA","field_23":[{"id": 6, "data": "Guru", "attributes": {"text": "#FFFFFF", "color": "#0D47A1"}}],"field_13":"Guru"},{"field_1":"Jacob","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": null, "data": null}],"field_6":[{"id": null, "data": null}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": null, "data": null}],"field_5":null,"field_23":[{"id": null, "data": null, "attributes": null}],"field_13":null},{"field_1":"John","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": 2, "data": "Green"}],"field_6":[{"id": 32, "data": "Nancy - 32"}, {"id": 35, "data": "Bobby - 35"}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": 32, "data": "ggñ@cnn.com"}, {"id": 35, "data": "Oliver@yahoo.com"}],"field_5":null,"field_23":[{"id": 4, "data": "Experienced", "attributes": {"text": "#FFFFFF", "color": "#C79702"}}, {"id": 5, "data": "Expert", "attributes": {"text": "#FFFFFF", "color": "#448AFF"}}],"field_13":"Expert"},{"field_1":"Todd","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": 4, "data": "Yellow"}],"field_6":[{"id": 1, "data": "Bobbie - 1"}, {"id": 4, "data": "bobby - 4"}],"field_8":[{"id": 1, "data": "Please stand up"}],"field_21":[{"id": 1, "data": "paul@sonos.com"}, {"id": 4, "data": "ggñ@cnn.com"}],"field_5":"MA","field_23":[{"id": 2, "data": "Novice", "attributes": {"text": "#000000", "color": "#FFEB3B"}}, {"id": 3, "data": "Intermediate", "attributes": {"text": "#000000", "color": "#F5F5F5"}}],"field_13":"Intermediate"}]

这是我想要得到的输出。

{count: 5, data:[{"field_1":"Billy","field_2":null,"field_4":[{"id": 4, "data": "Senior Javascript Engineer"}, {"id": 5, "data": "Recruiter"}],"field_9":[{"id": 1, "data": "Blue"}],"field_6":[{"id": 32, "data": "Nancy - 32"}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": 32, "data": "ggñ@cnn.com"}],"field_5":null,"field_23":[{"id": 5, "data": "Expert", "attributes": {"text": "#FFFFFF", "color": "#448AFF"}}],"field_13":"Expert"},{"field_1":"Jackson","field_2":null,"field_4":[{"id": 2, "data": "Marketing Manager M1004"}, {"id": 4, "data": "Senior Javascript Engineer"}, {"id": 5, "data": "Recruiter"}],"field_9":[{"id": 3, "data": "Red"}],"field_6":[{"id": 36, "data": ",Mike - 36"}],"field_8":[{"id": 2, "data": "Henry"}],"field_21":[{"id": 36, "data": "PtereSwanson@gmail.com"}],"field_5":"CA","field_23":[{"id": 6, "data": "Guru", "attributes": {"text": "#FFFFFF", "color": "#0D47A1"}}],"field_13":"Guru"},{"field_1":"Jacob","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": null, "data": null}],"field_6":[{"id": null, "data": null}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": null, "data": null}],"field_5":null,"field_23":[{"id": null, "data": null, "attributes": null}],"field_13":null},{"field_1":"John","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": 2, "data": "Green"}],"field_6":[{"id": 32, "data": "Nancy - 32"}, {"id": 35, "data": "Bobby - 35"}],"field_8":[{"id": null, "data": null}],"field_21":[{"id": 32, "data": "ggñ@cnn.com"}, {"id": 35, "data": "Oliver@yahoo.com"}],"field_5":null,"field_23":[{"id": 4, "data": "Experienced", "attributes": {"text": "#FFFFFF", "color": "#C79702"}}, {"id": 5, "data": "Expert", "attributes": {"text": "#FFFFFF", "color": "#448AFF"}}],"field_13":"Expert"},{"field_1":"Todd","field_2":null,"field_4":[{"id": null, "data": null}],"field_9":[{"id": 4, "data": "Yellow"}],"field_6":[{"id": 1, "data": "Bobbie - 1"}, {"id": 4, "data": "bobby - 4"}],"field_8":[{"id": 1, "data": "Please stand up"}],"field_21":[{"id": 1, "data": "paul@sonos.com"}, {"id": 4, "data": "ggñ@cnn.com"}],"field_5":"MA","field_23":[{"id": 2, "data": "Novice", "attributes": {"text": "#000000", "color": "#FFEB3B"}}, {"id": 3, "data": "Intermediate", "attributes": {"text": "#000000", "color": "#F5F5F5"}}],"field_13":"Intermediate"}]}

我希望在顶级属性中返回总记录,与数据结果分开。 我该怎么做,我尝试添加基表count(a.id),但它不返回总记录。

【问题讨论】:

  • 需要样本数据和所需的输出才能获得准确的查询
  • 好的,我用当前输出的例子更新了票证,然后我想生成什么。让我知道这是否足够。
  • 添加了答案。
  • 总记录数”是什么意思? select count(t), array_to_json(array_agg(t)) as data from (…) t 能解决问题吗?

标签: arrays postgresql jsonb


【解决方案1】:

使用json_array_length,因为您的最终输出是JSON Array 格式。

select jsonb_build_object('count',json_array_length(data),'data',data) from (
select array_to_json(array_agg(t)) data from (
select 
a.field_1,
a.field_2,
jsonb_agg(distinct jsonb_build_object('id',g.id,'data',g.fullname)) as field_4,
jsonb_agg(distinct jsonb_build_object('id',i.optionid,'data',i.option)) as field_9,
jsonb_agg(distinct jsonb_build_object('id',c.id,'data',c.fullname)) as field_6,
jsonb_agg(distinct jsonb_build_object('id',k.id,'data',k.fullname)) as field_8,
jsonb_agg(distinct jsonb_build_object('id',m.id,'data',m.field_20)) as field_21,
l.field_5,
jsonb_agg(distinct jsonb_build_object('id',e.optionid,'data',e.option,'attributes',e.attributes)) as field_23,
n.data as field_13,
jsonb_agg(distinct jsonb_build_object('id',bb.id,'data',bb.fullname)) as field_12

from schema_1.tbl_342 a
left join schema_1.tbl_342_to_tbl_329_field_10 b on a.id=b.tbl_342_id
left join schema_1.tbl_329_customid c on b.tbl_329_id=c.id
left join schema_1.tbl_329 m on m.id=b.tbl_329_id
left join schema_1.tbl_329_field_23_join d on c.id=d.id
left join schema_1.tbl_329_field_23 e on d.optionid = e.optionid
left join schema_1.tbl_342_to_tbl_312_field_4 f on a.id=f.tbl_342_id
left join schema_1.tbl_312_customid g on f.tbl_312_id = g.id
left join schema_1.tbl_342_field_9_join h on h.id=a.id
left join schema_1.tbl_342_field_9 i on i.optionid=h.optionid
left join schema_1.tbl_343_to_tbl_342_field_6 j on j.tbl_342_id=a.id
left join schema_1.tbl_343_customid k on j.tbl_343_id=k.id
left join schema_1.tbl_343 l on l.id=j.tbl_343_id
left join schema_1.tbl_342_field_13_max n on n.id=a.id
group by a.field_1,a.field_2,l.field_5,m.field_23,n.data
) t)x

它会给你想要的输出

根据评论更新

with cte as (
select 
a.field_1,
a.field_2,
jsonb_agg(distinct jsonb_build_object('id',g.id,'data',g.fullname)) as field_4,
jsonb_agg(distinct jsonb_build_object('id',i.optionid,'data',i.option)) as field_9,
jsonb_agg(distinct jsonb_build_object('id',c.id,'data',c.fullname)) as field_6,
jsonb_agg(distinct jsonb_build_object('id',k.id,'data',k.fullname)) as field_8,
jsonb_agg(distinct jsonb_build_object('id',m.id,'data',m.field_20)) as field_21,
l.field_5,
jsonb_agg(distinct jsonb_build_object('id',e.optionid,'data',e.option,'attributes',e.attributes)) as field_23,
n.data as field_13,
jsonb_agg(distinct jsonb_build_object('id',bb.id,'data',bb.fullname)) as field_12

from schema_1.tbl_342 a
left join schema_1.tbl_342_to_tbl_329_field_10 b on a.id=b.tbl_342_id
left join schema_1.tbl_329_customid c on b.tbl_329_id=c.id
left join schema_1.tbl_329 m on m.id=b.tbl_329_id
left join schema_1.tbl_329_field_23_join d on c.id=d.id
left join schema_1.tbl_329_field_23 e on d.optionid = e.optionid
left join schema_1.tbl_342_to_tbl_312_field_4 f on a.id=f.tbl_342_id
left join schema_1.tbl_312_customid g on f.tbl_312_id = g.id
left join schema_1.tbl_342_field_9_join h on h.id=a.id
left join schema_1.tbl_342_field_9 i on i.optionid=h.optionid
left join schema_1.tbl_343_to_tbl_342_field_6 j on j.tbl_342_id=a.id
left join schema_1.tbl_343_customid k on j.tbl_343_id=k.id
left join schema_1.tbl_343 l on l.id=j.tbl_343_id
left join schema_1.tbl_342_field_13_max n on n.id=a.id
group by a.field_1,a.field_2,l.field_5,m.field_23,n.data
),
cte2 as 
(select count(*) as "count_" from cte)

select row_to_json(x) from (
select cte2.count_ "count", array_to_json(array_agg(t)) as data from (
select * from cte limit 3 -- you can add desired limit here
 ) t, cte2
group by 1
)x

【讨论】:

  • 嗯,我实际上需要查询中的计数,因为我将添加 where 子句,因为最终,我将从更大的记录集中返回有限数量的记录。例如,查询可能有 15,000 条记录匹配,但返回的是前 500 条记录。在此示例中,我想显示 15,000 条查询中的匹配记录总数。我该怎么做?
  • 可以在group by前添加where子句
  • 是的,但在我的示例中,您的函数 json_array_length(data) 不会返回 500,而不是 15,000?
  • 表示您想要总记录数,然后只需要由 where 子句过滤的数据?
  • 例如,我将在上面的查询中添加限制 500。所以,即使匹配的记录可能是 15,000,我会带回前 500 个,并且将有分页以到达下一个 500,依此类推。但是当查询运行时,我想显示查询的总记录。也许这只能通过 2 个单独的查询来完成
猜你喜欢
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 2011-01-31
  • 1970-01-01
  • 2019-12-03
  • 2014-02-24
相关资源
最近更新 更多