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

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

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

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

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

【问题讨论】:

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

标签: postgresql postgresql-9.4


【解决方案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;
        猜你喜欢
        • 2018-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        • 2016-11-22
        • 1970-01-01
        相关资源
        最近更新 更多