如何在 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)
我会更简单一点:
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
从 to 修改而来的这两个函数(用于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() 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() t(x);
$f$ LANGUAGE sql IMMUTABLE;
您可以按如下方式使用它们:
SELECT json_array_castint('[1,2,3]')
这给出了预期的 return {1,2,3}
,如 integer[]
。如果您想知道为什么我在每个 SELECT
语句中连接一个空数组,那是因为如果您尝试转换一个空的 json
/jsonb
,则转换是有损的并且没有它array 到 integer[]
你会得到 no return (不需要)而不是一个空数组(如预期的那样)。用上面的方法当你做
SELECT json_array_castint('[]')
你会得到 {}
而不是什么都没有。请参阅 了解更多关于我添加该内容的原因。
在我的例子中,我必须将存储在 table 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}
我遇到需要将 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)
我会更简单一点:
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
从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() 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() t(x);
$f$ LANGUAGE sql IMMUTABLE;
您可以按如下方式使用它们:
SELECT json_array_castint('[1,2,3]')
这给出了预期的 return {1,2,3}
,如 integer[]
。如果您想知道为什么我在每个 SELECT
语句中连接一个空数组,那是因为如果您尝试转换一个空的 json
/jsonb
,则转换是有损的并且没有它array 到 integer[]
你会得到 no return (不需要)而不是一个空数组(如预期的那样)。用上面的方法当你做
SELECT json_array_castint('[]')
你会得到 {}
而不是什么都没有。请参阅
在我的例子中,我必须将存储在 table 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}