PostgreSQL 中 json 数组值的交集
Intersection of values of json array in PostgreSQL
在 PostgreSQL 9.4 中,我有一个 table 这样的:
id | array_json
---+----------------------------
1 | [{"type": "single", "field_id": 9},
| {"type": "range", "field_id": 2}, ...]
|
2 | [{"type": "single", "field_id": 10},
| {"type": "range", "field_id": 2}, ...]
...
我想得到 field_id 列 中所有 table[= 值的交集40=].
| field_id intersection
+-------
| 2
我的意思是:
1. 映射 field_id 第一行的值:[9, 2]
2. 映射 field_id 第二行的值:[10, 2]
n. 映射 field_id 值 n ...
...
last. 获取所有行的交集:[2](假设 table 只有两行)
谁能告诉我如何做到这一点?
非常感谢
您将需要一个聚合来与连续行的数组相交:
create or replace function array_intersect(anyarray, anyarray)
returns anyarray language sql
as $$
select
case
when is null then
when is null then
else
array(
select unnest()
intersect
select unnest())
end;
$$;
create aggregate array_intersect_agg (anyarray)
(
sfunc = array_intersect,
stype = anyarray
);
使用 jsonb_array_elements()
和 array_agg()
以整数数组的形式检索 field_ids
:
select id, array_agg(field_id) field_ids
from (
select id, (e->>'field_id')::int field_id
from a_table, jsonb_array_elements(array_json) e
) sub
group by 1
order by 1;
id | field_ids
----+-----------
1 | {9,2}
2 | {10,2}
(2 rows)
使用定义的交集聚合对所有行的数组进行交集:
select array_intersect_agg(field_ids)
from (
select id, array_agg(field_id) field_ids
from (
select id, (e->>'field_id')::int field_id
from a_table, jsonb_array_elements(array_json) e
) sub
group by 1
order by 1
) sub;
array_intersect_agg
---------------------
{2}
(1 row)
在 PostgreSQL 9.4 中,我有一个 table 这样的:
id | array_json
---+----------------------------
1 | [{"type": "single", "field_id": 9},
| {"type": "range", "field_id": 2}, ...]
|
2 | [{"type": "single", "field_id": 10},
| {"type": "range", "field_id": 2}, ...]
...
我想得到 field_id 列 中所有 table[= 值的交集40=].
| field_id intersection
+-------
| 2
我的意思是:
1. 映射 field_id 第一行的值:[9, 2]
2. 映射 field_id 第二行的值:[10, 2]
n. 映射 field_id 值 n ...
...
last. 获取所有行的交集:[2](假设 table 只有两行)
谁能告诉我如何做到这一点?
非常感谢
您将需要一个聚合来与连续行的数组相交:
create or replace function array_intersect(anyarray, anyarray)
returns anyarray language sql
as $$
select
case
when is null then
when is null then
else
array(
select unnest()
intersect
select unnest())
end;
$$;
create aggregate array_intersect_agg (anyarray)
(
sfunc = array_intersect,
stype = anyarray
);
使用 jsonb_array_elements()
和 array_agg()
以整数数组的形式检索 field_ids
:
select id, array_agg(field_id) field_ids
from (
select id, (e->>'field_id')::int field_id
from a_table, jsonb_array_elements(array_json) e
) sub
group by 1
order by 1;
id | field_ids
----+-----------
1 | {9,2}
2 | {10,2}
(2 rows)
使用定义的交集聚合对所有行的数组进行交集:
select array_intersect_agg(field_ids)
from (
select id, array_agg(field_id) field_ids
from (
select id, (e->>'field_id')::int field_id
from a_table, jsonb_array_elements(array_json) e
) sub
group by 1
order by 1
) sub;
array_intersect_agg
---------------------
{2}
(1 row)