在postgresql中迭代json数组元素

在postgresql中迭代json数组元素,sql,json,postgresql,plpgsql,Sql,Json,Postgresql,Plpgsql,我有一个json,看起来像这样 { "elements": [ "element1", "element2", "element3" ] } do $$ declare datajson jsonb := '{ "elements": [ "element1", "element2", "element3", "element4" ] }'; element varchar(128); begin foreach element in a

我有一个json,看起来像这样

{
    "elements": [ "element1", "element2", "element3" ]
}
do $$
declare
    datajson jsonb := '{
        "elements": [ "element1", "element2", "element3", "element4" ]
    }';
    element varchar(128);
begin
    foreach element in array jsonb_array_elements(datajson->'elements')
    loop
        raise notice '%', element;
    end loop;
end;
$$;
我想迭代它的元素并打印它们。 我是这样做的

{
    "elements": [ "element1", "element2", "element3" ]
}
do $$
declare
    datajson jsonb := '{
        "elements": [ "element1", "element2", "element3", "element4" ]
    }';
    element varchar(128);
begin
    foreach element in array jsonb_array_elements(datajson->'elements')
    loop
        raise notice '%', element;
    end loop;
end;
$$;
但是它失败了,错误是
queryselectjsonb_数组_元素(datajson->'elements')返回了多行

有什么问题

更新

我试过这个建议:

do $$
declare
    datajson jsonb := '{
        "elements": [ "element1", "element2", "element3", "element4" ]
    }';
    element varchar(128);
begin
    foreach element in array
        SELECT array_agg(jsonb_array_elements) FROM jsonb_array_elements(datajson->'elements')
    loop
        raise notice '%', element;
    end loop;
end;
$$;
但这只是给出了一个语法错误:

ERROR:  42601: syntax error at or near "SELECT"
LINE 7:     SELECT array_agg(jsonb_array_elements) FROM jsonb_array_...
            ^
LOCATION:  scanner_yyerror, scan.l:1134
尝试在不使用(…)中的r的
并声明
记录
变量的情况下执行此操作。

只需:

so=# with c(j) as (values('{
    "elements": [ "element1", "element2", "element3" ]
}'::jsonb))
select jsonb_array_elements(j->'elements') from c;
 jsonb_array_elements
----------------------
 "element1"
 "element2"
 "element3"
(3 rows)
但如果你想提高它:

so=# do $$
declare
    datajson jsonb := '{
        "elements": [ "element1", "element2", "element3", "element4" ]
    }';
    element varchar(128);
    r record;
begin
    for r in (select jsonb_array_elements(datajson->'elements') element)
    loop
        raise notice '%', r.element;
    end loop;
end;
$$;
NOTICE:  "element1"
NOTICE:  "element2"
NOTICE:  "element3"
NOTICE:  "element4"
DO
我假设你混淆了json数组和postgres数组——它们不一样。和
jsonb_数组_元素
,而不是数组

jsonb_数组_元素()
将数组的元素作为表而不是数组返回

使用

迭代表行,而不是数组

或者使用
array\u agg()
将表转换为数组:

FOREACH element IN ARRAY
    SELECT array_agg(jsonb_array_elements) FROM jsonb_array_elements(datajson->'elements')
LOOP
     ...
END LOOP;

但它的工作速度可能会慢一些(表将像前一种情况一样创建,然后进行转换)

所以它基本上返回一个只有一列的表?我可以把它转换成数组吗?可以。编辑了答案。第二个示例不起作用:获取
错误:42601:在“选择”
处或附近出现语法错误-使用版本11。还尝试将子查询放在括号中,但结果相同。@user9645请检查您是否忘记了
循环。。。端环。请注意,我没有Postgres 11来测试答案。我没有忘记循环/结束循环-我只是将数组SELECT…
语句中的
FOREACH元素粘贴到我的测试用例中,并获得
错误:42601:在“SELECT”处或附近出现语法错误
第7行:选择数组(jsonb_数组_元素)从jsonb_array_u…
位置:scanner_yyerror,scan.l:1134
我建议您验证是否可以对类似的
SELECT
语句使用
数组。如果每个条目在
{“name”:“value”,“fields”:[“a1”,“a2”]之类的字段中都有自己的子数组,该怎么办
?写一个递归的CTE我想说谢谢-我知道如何使用(…)中的r
,但我希望避免声明一个
记录
变量。