Return Postgres 数组中的一系列元素 json

Return a range of elements from an array in Postgres json

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

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

上面的脚本 return 第三个元素 "c".

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

您可以将 json 数组转换为实际数组,方法是将文本表示形式从 '["a","b","c"]' 更改为 '{"a","b","c"}',并将结果转换为 text[]

然后就可以使用常用的Postgres数组下标了:

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

returns

{a,b}

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

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)

您可以创建自己的函数(因为 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) 

在 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)