我目前正在处理 PostgreSQL 查询,以从 JSONB 列中提取特定值。这是我正在使用的查询:
select
a.id,
(jsonb_array_elements(a.info->'attribute1')->>'value') as attribute1,
(a.info->>'attribute2') as attribute2,
(a.info->>'attribute3') as attribute3,
(jsonb_array_elements(a.info->'attribute4')->>'value') as attribute4
from a_table a
where
(cast(a.info->>'attribute3' as NUMERIC) > 0
or jsonb_array_length(a.info->'attribute1') > 0
or jsonb_array_length(a.info->'attribute4') > 0
or cast(a.info->>'attribute2' as NUMERIC) > 0)
and a.active=true
and a.data='AAA0000'
我面临的问题是,它复制
attribute3
的次数与 attribute1
(或具有更多寄存器的任何其他属性)一样多,当我使用此查询作为子查询对所有列的值求和时,会创建不正确的结果。
该查询的结果如下:
以下是先前结果的信息列中的数据示例。可以看出,之前的结果对于attribute3来说是不正确的。
{
"attribute1": [{"value": 30.45, "description": "abc1"}, {"value": 5, "description": "abc2"}, {"value": 5, "description": "abc3"}],
"attribute2": 0,
"attribute3": 69.36,
"attribute4": [{"value": 18, "description": "aaa"}]
}
我正在寻找一种修改查询以防止复制属性值的方法。
我面临的问题是它复制
的次数与attribute3
(或具有更多寄存器的任何其他属性)一样多......attribute1
实际上,您可以获得所有涉及的基数的笛卡尔积。实际上是通过
CROSS JOIN
取消嵌套产生的所有集合之间的 jsonb_array_elements()
。
避免这种行乘法的一种方法是聚合复制,即将每个生成集聚合到一个数组中。喜欢:
SELECT a.id
, ARRAY(SELECT jsonb_array_elements(a.info -> 'attribute1') ->> 'value') AS attribute1
, (a.info ->> 'attribute2') AS attribute2
, (a.info ->> 'attribute3') AS attribute3
, ARRAY(SELECT jsonb_array_elements(a.info -> 'attribute4') ->> 'value') AS attribute4
FROM ...