【问题标题】:How to convert json array into postgres int array in postgres 9.3如何在 postgres 9.3 中将 json 数组转换为 postgres int 数组
【发布时间】:2016-06-07 17:57:03
【问题描述】:

我有一个场景,我需要将一个 json 数组转换为 postgres int 数组并查询它的结果。下面是我的数组

      ID            DATA
       1           {"bookIds" : [1,2,3,5], "storeIds": [2,3]} 
       2           {"bookIds" : [4,5,6,7], "storeIds": [1,3]}
       3           {"bookIds" : [11,12,10,9], "storeIds": [4,3]}

我想将 booksId 数组转换为 int 数组,然后再查询它。在 postgres 9.3 中可以吗?我知道 9.4 + 提供了更多 JSON 支持,但我目前无法更新我的数据库。

下面的查询给我错误

  Select data::json->>'bookIds' :: int[] from table

 ERROR:  malformed array literal: "bookIds"
 LINE 1: Select data::json->>'bookIds' :: int[] from table

是否可以在 postgres 9.3 中查询 json 数组中的元素。提前谢谢...

【问题讨论】:

    标签: arrays json postgresql postgresql-9.3


    【解决方案1】:

    问题中的设置应如下所示:

    create table a_table (id int, data json);
    insert into a_table values
    (1, '{"bookIds": [1,2,3,5], "storeIds": [2,3]}'), 
    (2, '{"bookIds": [4,5,6,7], "storeIds": [1,3]}'),
    (3, '{"bookIds": [11,12,10,9], "storeIds": [4,3]}');
    

    注意 json 值的正确语法。

    你可以使用函数json_array_elements()

    select id, array_agg(e::text::int)
    from a_table, json_array_elements(data->'bookIds') e
    group by 1
    order by 1;
    
     id |  array_agg   
    ----+--------------
      1 | {1,2,3,5}
      2 | {4,5,6,7}
      3 | {11,12,10,9}
    (3 rows)    
    

    使用any() 搜索数组中的元素,例如:

    select *
    from (
        select id, array_agg(e::text::int) arr
        from a_table, json_array_elements(data->'bookIds') e
        group by 1
        ) s
    where 
        1 = any(arr) or
        11 = any(arr);
    
     id |     arr      
    ----+--------------
      1 | {1,2,3,5}
      3 | {11,12,10,9}
    (2 rows)
    

    另请阅读<@ operator

    您还可以通过检查其元素在 json 数组中搜索(不将其转换为 int 数组),例如:

    select t.*
    from a_table t, json_array_elements(data->'bookIds') e
    where e::text::int in (1, 11);
    
     id |                     data                      
    ----+-----------------------------------------------
      1 | {"bookIds" : [1,2,3,5], "storeIds": [2,3]}
      3 | {"bookIds" : [11,12,10,9], "storeIds": [4,3]}
    (2 rows)
    

    【讨论】:

    • 谢谢你的回答,我的问题是如何搜索元素比?假设我想搜索包含 1 和 11 的行。
    • 这就像一种魅力,但只有当我搜索同一行的多个元素时才会出现重复的问题。例如 select t.* from a_table t, json_array_elements(data->'bookIds') e where e::text::int = any ('{1, 2}' :: int[]);它给了我第一排两次。我可以申请不同的。
    【解决方案2】:

    这两个函数(用于json/jsonb)从a fantastic answer修改为this question完美运行

    CREATE OR REPLACE FUNCTION json_array_castint(json) RETURNS int[] AS $f$
        SELECT array_agg(x)::int[] || ARRAY[]::int[] FROM json_array_elements_text($1) t(x);
    $f$ LANGUAGE sql IMMUTABLE;
    
    CREATE OR REPLACE FUNCTION jsonb_array_castint(jsonb) RETURNS int[] AS $f$
        SELECT array_agg(x)::int[] || ARRAY[]::int[] FROM jsonb_array_elements_text($1) t(x);
    $f$ LANGUAGE sql IMMUTABLE;
    

    您可以按如下方式使用它们:

    SELECT json_array_castint('[1,2,3]')
    

    这给出了预期的回报{1,2,3},如integer[]。如果您想知道为什么我在每个 SELECT 语句中连接一个空数组,那是因为如果您尝试将一个空的 json/jsonb 数组转换为 integer[]你不会得到任何回报(不需要),而不是一个空数组(如预期的那样)。做的时候用上面的方法

    SELECT json_array_castint('[]')
    

    你会得到{} 而不是什么都没有。请参阅 here 了解我添加此内容的原因。

    【讨论】:

      【解决方案3】:

      我会简单一点:

      select * from
      (
      select t.id, value::text::int as bookvalue
        from testjson t, json_array_elements(t.data->'bookIds')
      ) as t
      where bookvalue in (1,11)
      

      在这里查看它的工作原理:http://sqlfiddle.com/#!15/e69aa/37

      【讨论】:

        【解决方案4】:

        就我而言,我必须将存储在表 col 中的 json 数据转换为 pg 数组格式,这很方便:

        -- username is the table column, which has values like ["john","pete","kat"]
        
        select id, ARRAY(SELECT json_array_elements_text((username)::json)) usernames
        from public.table-name;
        
        -- this produces : {john,pete,kat}
        

        【讨论】:

          猜你喜欢
          • 2015-04-03
          • 1970-01-01
          • 1970-01-01
          • 2015-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多