Das, was einem Array-Schnittpunkt am nächsten kommt, ist Folgendes:
select array_agg(e)
from (
select unnest(a1)
intersect
select unnest(a2)
) as dt(e)
Dies setzt voraus, dass a1
und a2
sind eindimensionale Arrays mit demselben Elementtyp. Sie könnten das in einer Funktion wie dieser zusammenfassen:
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;
Dann könnten Sie Folgendes tun:
=> 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)
Beachten Sie, dass dies keine bestimmte Reihenfolge im zurückgegebenen Array garantiert, aber Sie können das beheben, wenn Sie sich darum kümmern. Dann könnten Sie Ihre eigene Aggregatfunktion erstellen:
-- 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[]
);
Und jetzt sehen wir, warum array_intersect
macht lustige und etwas klobige Sachen mit NULLen. Wir brauchen einen Anfangswert für die Aggregation, der sich wie das universelle Set verhält, und dafür können wir NULL verwenden (ja, das riecht etwas seltsam, aber mir fällt auf Anhieb nichts Besseres ein).
Sobald dies alles eingerichtet ist, können Sie Folgendes tun:
> 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)
Nicht gerade einfach oder effizient, aber vielleicht ein vernünftiger Ausgangspunkt und besser als gar nichts.
Nützliche Referenzen:
array_agg
- Aggregat erstellen
- Funktion erstellen
- PL/pgSQL
unnest