我想知道是否有可能将一个json对象'covnert'到一个json数组来迭代一组混合数据。
我有两行看起来像
{Data:{BASE:{B1:0,color:green}}}
{Data:{BASE:[{B1:1,color:red},{B1:0,color:blue}]}}
我想从所有这些行中提取B1 val,但我有点被阻止了:)
我的第一次尝试是json_extract_array,但它在第1行(不是数组)失败。 然后我的第二次尝试是带有一个案例的json_array_length,但是在第一行(不是数组)失败
我能以任何方式处理这种情况吗? 基本上我需要提取B1> gt的所有行。其中一个json数组(或对象)中的0可能返回包含B1>的节点0
答案 0 :(得分:2)
您的主要问题是混合json -> 'Data' -> 'BASE'
路径下的数据类型,这是无法轻松处理的。我可以提出一个解决方案,但你应该修复你的架构,f.ex。只包含该路径上的数组。
with v(j) as (
values (json '{"Data":{"BASE":{"B1":0,"color":"green"}}}'),
('{"Data":{"BASE":[{"B1":1,"color":"red"},{"B1":0,"color":"blue"}]}}')
)
select j, node
from v,
lateral (select j #> '{Data,BASE}') b(b),
lateral (select substring(trim(leading E'\x20\x09\x0A\x0D' from b::text) from 1 for 1)) l(l),
lateral (select case
when l = '{' and (b #>> '{B1}')::numeric > 0 then b
when l = '[' then (select e from json_array_elements(b) e where (e #>> '{B1}')::numeric > 0 limit 1)
else null
end) node(node)
where node is not null
答案 1 :(得分:1)
返回至少有一个对象具有B1 > 0
select *
from t
where true in (
select (j ->> 'B1')::int > 0
from json_array_elements (json_column -> 'Data' -> 'BASE') s (j)
)
答案 2 :(得分:0)
在这里得到其他答案的一点帮助后,我这样做了:
1
将它划分为两个查询,一个只提取一个值,如果只有一个,则一个查询,如果有多个则解包该数组,如果你要求提供文本,PostgreSQL会返回with v(j) as (
values (json '{"Data":{"BASE":{"B1":0,"color":"green"}}}'),
('{"Data":{"BASE":[{"B1":1,"color":"red"},{"B1":0,"color":"blue"}]}}')
)
select j->'Data'->'BASE'->>'B1' as "B1"
from v
where j->'Data'->'BASE'->>'B1' is not null
union all
select json_array_elements(j->'Data'->'BASE')->>'B1'
from v
where j->'Data'->'BASE'->>'B1' is null
那是一个数组。然后,我刚刚将两个查询的结果联合起来,结果是:
null