如何聚合子查询中的多行?
How to aggregate multiple rows from subquery?
我想为每个 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
你可以在table中使用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
我认为您需要使用横向连接来执行此操作:
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;
我想为每个 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
你可以在table中使用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
我认为您需要使用横向连接来执行此操作:
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;