从 Postgres json 中的数组返回一系列元素

Posted

技术标签:

【中文标题】从 Postgres json 中的数组返回一系列元素【英文标题】:Return a range of elements from an array in Postgres json 【发布时间】:2016-11-02 09:39:22 【问题描述】:

众所周知,在 Postgres json 中,我们可以使用以下方法从数组中获取指定索引处的一个元素:

["a","b","c"]::json -> 2

上面的脚本返回第三个元素“c”。

如果我指定一个索引范围,例如0到20,有什么方法可以返回一个元素范围?

【问题讨论】:

谢谢大家,你们的回答都很有帮助。此外,我的数组在实践中的元素数量超过20000,谁能告诉我哪种方式性能最好,tks。 【参考方案1】:

在 PostgreSQL 12 中,我设法使用 jsonb_path_query_array 函数设计了 JSONB 数组切片,如下所示:

SELECT jsonb_path_query_array('["a","b","c","d","e","f"]', '$[2 to 4]');
 jsonb_path_query_array
------------------------
 ["c", "d", "e"]
(1 row)

【讨论】:

【参考方案2】:

您可以创建自己的函数(因为 Postgres 中没有这样的功能):

create or replace function json_sub_array(json_array json, from_pos int, to_pos int)
returns json language sql as $$
    select json_agg(value)
    from json_array_elements(json_array) with ordinality
    where ordinality-1 between from_pos and to_pos
$$;

select json_sub_array('["a","b","c","d"]'::json, 1, 2);

 json_sub_array 
----------------
 ["b", "c"]
(1 row) 

【讨论】:

【参考方案3】:

您可以通过将文本表示形式从 '["a","b","c"]' 更改为 '"a","b","c"' 并将结果转换为 text[] 来将 json 数组转换为真实数组。

那么就可以使用常用的Postgres数组下标了:

select (translate('["a","b","c"]'::json::text, '[]','')::text[])[1:2]

返回

a,b

请注意,原生 Postgres 数组是从 1 开始的(第一个元素的索引为 1),这与从 0 开始的 JSON 数组不同。

【讨论】:

【参考方案4】:

json_array_elementsrow_number 为例:

db=> select value
     from (select row_number() over (), value
           from json_array_elements('["a","b","c"]'::json)
     ) as t
     where row_number between 2 and 3;
 value 
-------
 "b"
 "c"
(2 rows)

或使用WITH ORDINALITY

db=> select value
     from json_array_elements('["a","b","c"]'::json)
     with ordinality
     where ordinality between 2 and 3;
 value 
-------
 "b"
 "c"
(2 rows)

【讨论】:

你能告诉我哪种方式性能更好吗?我的数组非常大。 @YinAqu with ordinality 应该更快(没有显式连接来获取行号) Tks,请你帮我检查一下这个 sql,子查询是错误的语法。从 json_array_elements 中选择值(从 hfj_search 中选择 result_json,其中 search_uuid='16aa6bd4-0b8b-403b-b165-efaab863bf7e'),其中序数介于 2 和 3 之间; @YinAqu 尝试为子查询添加额外的括号:select value from json_array_elements( (subquery in parentheses) ) with ordinality where ordinality between 2 and 3; 需要显式类型转换,这可行:select value from json_array_elements( (subquery in parentheses)::json ) with ordinality where ordinality between 2 and 3;

以上是关于从 Postgres json 中的数组返回一系列元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Postgres 中选择一列 json 对象,以便返回的行是 json 数组?

在 Postgres 9.4 中查找 JSON 数组中的最后一项

在 SQL (Postgres) 中作为 JSON 对象数组返回

Postgres选择包含json的json数组中的位置

从 psycopg2 在 Postgres 中插入 dict 列表作为 json 数组

如何将 JSON 数组从 NodeJS 流式传输到 postgres