繁体   English   中英

如何在 postgres 9.3 中将 json 数组转换为 postgres int 数组

[英]How to convert json array into postgres int array in postgres 9.3

我有一个场景,我需要将一个 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 数组中的元素.. 提前致谢...

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

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)

这两个函数(对于json / jsonb )从对这个问题的精彩答案修改而来,效果很好

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('[]')

您将获得{}而不是什么都没有。 请参阅此处了解有关我添加该内容的原因的更多信息。

我会更简单一点:

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

在我的情况下,我不得不将存储在表 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}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM