sql >> Database teknologi >  >> RDS >> PostgreSQL

Skæring af flere arrays i PostgreSQL

Det tætteste på et array skæringspunkt, som jeg kan komme i tanke om, er dette:

select array_agg(e)
from (
    select unnest(a1)
    intersect
    select unnest(a2)
) as dt(e)
 

Dette forudsætter, at a1 og a2 er enkeltdimensionsarrays med den samme type elementer. Du kan pakke det ind i en funktion som denne:

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;
 

Så kunne du gøre ting som dette:

=> 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)
 

Bemærk, at dette ikke garanterer nogen bestemt rækkefølge i det returnerede array, men du kan ordne det, hvis du bekymrer dig om det. Så kan du oprette din egen aggregerede funktion:

-- 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[] );

Og nu ser vi hvorfor array_intersect laver sjove og lidt klodsede ting med NULLs. Vi har brug for en startværdi for aggregeringen, der opfører sig som det universelle sæt, og vi kan bruge NULL til det (ja, det lugter lidt, men jeg kan ikke komme i tanke om noget bedre fra toppen af ​​mit hoved).

Når alt dette er på plads, kan du gøre ting som dette:

> 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)
 

Ikke ligefrem simpelt eller effektivt, men måske et fornuftigt udgangspunkt og bedre end slet ingenting.

Nyttige referencer:

  • array_agg
  • opret aggregat
  • opret funktion
  • PL/pgSQL
  • unnest


  1. Sådan implementeres applikation med sql-serverdatabase på klienter

  2. Hvordan man erklærer en variabel i en PostgreSQL-forespørgsel

  3. Forespørgsel for at kontrollere tabelstørrelsen i Oracle-databasen

  4. Forbedring af top/top faldende medianløsning