我想为每个prod_id获取chd_id的数组,
下面的查询有效,但仅适用于limit 1
,但我希望获得准确的结果,但需要多行
select
prod_id,
array_agg((select * from jsonb_array_elements(products.prod_prop) limit 1)->>'chd_id')
from products
group by prod_id
limit 10
当前结果:
products.prod_prop
的原始值为
[{"val": ["xxx"], "chd_id": 25812}, {"val": ["yyy"], "chd_id": 2342}]
没有limit 1
,我得到ERROR: more than one row returned by a subquery used as an expression
答案 0 :(得分:2)
您可以在表和通过使用CROSS JOIN
函数生成的子查询中使用jsonb_array_elements()
:
SELECT p.prod_id, array_agg(j.e->>'chd_id') AS chd_id
FROM products p
CROSS JOIN jsonb_array_elements(prod_prop) j(e)
GROUP BY prod_id
答案 1 :(得分:2)
我认为您需要通过横向连接来做到这一点:
select prod_id,
array_agg(t.chd_id)
from products p
left join lateral (
select e ->> 'chd_id' as chd_id
from jsonb_array_elements(p.prod_prop) as t(e)
) t on true
group by prod_id
limit 10;
如果prod_prop值为空,则需要外部联接
显然,JSONB中的数据有时是数组,有时是纯对象。如果所有“普通对象”确实都是空值,则可以使用以下方法解决该问题:
select prod_id,
array_agg(t.chd_id) filter (where t.chd_id is not null)
from products p
left join lateral (
select e ->> 'chd_id' as chd_id
from jsonb_array_elements(nullif(p.prod_prop,'{}')) as t(e)
) t on true
group by prod_id
limit 10;
如果确实在该列中混合了普通对象和数组,则需要另一种方法:
select prod_id,
array_agg(t.chd_id) filter (where t.chd_id is not null)
from products p
left join lateral (
select e ->> 'chd_id' as chd_id
from jsonb_array_elements(case jsonb_typeof(p.prod_prop)
when 'array' then p.prod_prop
else '[]'
end) as t(e)
) t on true
group by prod_id
limit 10;