[英]PostgreSQL: Extract specific information from json
I'm using PostgreSQL 9.6 and I have the following table, let's call it table1
:我正在使用 PostgreSQL 9.6,我有下表,我们称之为table1
:
id | json_data
____________________
200 | {"state": [3, 4, 5]}
I want to be able to perform the following query: extract the array inside the "state"
key in json_data
for the record with id 1
, but also remove some of the integers from the array in the process.我希望能够执行以下查询:在json_data
中的"state"
键中提取 id 为1
的记录的数组,同时在该过程中从数组中删除一些整数。
For example (in pseudo-code):例如(在伪代码中):
extract_state(id = 200, remove_numbers_from_json_data_state = [3, 5])
should return [4]
extract_state(id = 200, remove_numbers_from_json_data_state = [3, 5])
应该返回[4]
There is no built-in function for that, but you can easily write your own:没有内置的 function ,但您可以轻松编写自己的:
create function remove_numbers(p_array jsonb, p_nr variadic int[] )
returns jsonb
as
$$
select jsonb_agg(x)
from jsonb_array_elements(p_array) as t(x)
where t.x::int <> ALL(p_nr);
$$
language sql
immutable;
Then you can use it like this:然后你可以像这样使用它:
select id, remove_numbers(json_data -> 'state', 4,5)
from t1
where id = 1;
If you prefer to pass a JSON array value, you can define the function like this:如果您更喜欢传递 JSON 数组值,您可以像这样定义 function:
create function remove_numbers(p_array jsonb, p_to_remove jsonb)
returns jsonb
as
$$
select jsonb_agg(x)
from jsonb_array_elements(p_array) as t(x)
where t.x not in (select *
from jsonb_array_elements(p_to_remove))
$$
language sql;
Then you would need to use remove_numbers(json_data -> 'state', '[4,5]')
然后你需要使用remove_numbers(json_data -> 'state', '[4,5]')
You'd use a query like this:你会使用这样的查询:
SELECT json_data->'state'->>1 FROM table1 WHERE id = 200;
You can test this way, without having a table:您可以通过这种方式进行测试,而无需使用表格:
SELECT '{"state": [3, 4, 5]}'::jsonb->'state'->>1
Here is a reference for using JSON in Postgres: https://www.postgresql.org/docs/current/functions-json.html Here is a reference for using JSON in Postgres: https://www.postgresql.org/docs/current/functions-json.html
It returns 4
, not [4]
, so if you need to, you could select it as an array:它返回4
,而不是[4]
,所以如果你需要,你可以 select 它作为一个数组:
SELECT ARRAY[('{"state": [3, 4, 5]}'::jsonb->'state'->>1)::int]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.