遍历postgresql中的json数组元素
Posted
技术标签:
【中文标题】遍历postgresql中的json数组元素【英文标题】:iterate over json array elements in postgresql 【发布时间】:2018-05-16 09:59:50 【问题描述】:我有一个像这样的 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;
$$;
但它失败并出现错误query select jsonb_array_elements(datajson->'elements') returned more than one row
。
有什么问题?
更新
试过这个建议:
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
尝试在不使用 FOR r IN (...)
并声明 RECORD
变量的情况下执行此操作。
【问题讨论】:
【参考方案1】:只是:
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_array_elements
returns setof,不是数组
【讨论】:
如果每个条目在 "name" : "value", "fields": ["a1", "a2"]
这样的字段中都有自己的子数组怎么办?
写一个我想说的递归 CTE
谢谢 - 我知道如何使用 FOR r IN (...)
,但我希望避免声明 RECORD
变量。【参考方案2】:
jsonb_array_elements()
将数组的元素作为表返回,而不是作为数组。
使用
FOR element IN
SELECT jsonb_array_elements FROM jsonb_array_elements(datajson->'elements')
LOOP
...
END LOOP;
遍历表格行,而不是数组。
或者使用array_agg()
将表格转为数组:
FOREACH element IN ARRAY
(SELECT array_agg(jsonb_array_elements) FROM jsonb_array_elements(datajson->'elements'))
LOOP
...
END LOOP;
但它可能工作较慢(表将像以前的情况一样创建,然后将被转换)
【讨论】:
所以基本上它返回一个单列的表?我可以把它转换成数组吗? 是的。编辑了答案。 第二个示例不起作用:获取ERROR: 42601: syntax error at or near "SELECT"
- 使用版本 11。还尝试将子查询放在括号中,但结果相同。
@user9645 请检查您是否忘记了LOOP ... END LOOP;
。请注意,我没有 Postgres 11 来测试答案。
我没有忘记循环/结束循环 - 我只是将你的 FOREACH element in ARRAY SELECT...
语句粘贴到我的测试用例中并得到 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
我建议你验证你可以使用 @ 987654331@ 反对 SELECT
这样的声明。以上是关于遍历postgresql中的json数组元素的主要内容,如果未能解决你的问题,请参考以下文章
将包含对象数组的 json 传递给 PostgreSQL 函数会引发格式错误的数组文字。意外的数组元素