Hal terdekat dengan persimpangan array yang dapat saya pikirkan adalah ini:
select array_agg(e)
from (
select unnest(a1)
intersect
select unnest(a2)
) as dt(e)
Ini mengasumsikan bahwa a1
dan a2
adalah array dimensi tunggal dengan jenis elemen yang sama. Anda bisa membungkusnya dengan fungsi seperti ini:
create function array_intersect(a1 int[], a2 int[]) returns int[] as $$
declare
ret int[];
begin
-- The reason for the kludgy NULL handling comes later.
if a1 is null then
return a2;
elseif a2 is null then
return a1;
end if;
select array_agg(e) into ret
from (
select unnest(a1)
intersect
select unnest(a2)
) as dt(e);
return ret;
end;
$$ language plpgsql;
Kemudian Anda dapat melakukan hal-hal seperti ini:
=> select array_intersect(ARRAY[2,4,6,8,10], ARRAY[1,2,3,4,5,6,7,8,9,10]);
array_intersect
-----------------
{6,2,4,10,8}
(1 row)
Perhatikan bahwa ini tidak menjamin urutan tertentu dalam array yang dikembalikan tetapi Anda dapat memperbaikinya jika Anda peduli. Kemudian Anda dapat membuat fungsi agregat Anda sendiri:
-- Pre-9.1
create aggregate array_intersect_agg(
sfunc = array_intersect,
basetype = int[],
stype = int[],
initcond = NULL
);
-- 9.1+ (AFAIK, I don't have 9.1 handy at the moment
-- see the comments below.
create aggregate array_intersect_agg(int[]) (
sfunc = array_intersect,
stype = int[]
);
Dan sekarang kita melihat mengapa array_intersect
melakukan hal-hal lucu dan agak kludgey dengan NULL. Kita membutuhkan nilai awal untuk agregasi yang berperilaku seperti himpunan universal dan kita dapat menggunakan NULL untuk itu (ya, ini agak aneh tapi saya tidak bisa memikirkan yang lebih baik dari atas kepala saya).
Setelah semua ini tersedia, Anda dapat melakukan hal-hal seperti ini:
> select * from stuff;
a
---------
{1,2,3}
{1,2,3}
{3,4,5}
(3 rows)
> select array_intersect_agg(a) from stuff;
array_intersect_agg
---------------------
{3}
(1 row)
Tidak terlalu sederhana atau efisien, tetapi mungkin merupakan titik awal yang masuk akal dan lebih baik daripada tidak sama sekali.
Referensi yang berguna:
array_agg
- buat agregat
- buat fungsi
- PL/pgSQL
unnest