postgres + json对象到数组

时间:2014-07-04 09:22:14

标签: arrays json postgresql postgresql-json

我想知道是否有可能将一个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

3 个答案:

答案 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

SQLFiddle

答案 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