PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Persimpangan beberapa array di PostgreSQL

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ikhtisar pgModeler untuk PostgreSQL

  2. Menjalankan skrip SQL melalui psql memberikan kesalahan sintaks yang tidak terjadi di PgAdmin

  3. Cara Mengonversi Kasus String di PostgreSQL

  4. Pemicu acara ROLLBACK di postgresql

  5. Bisakah saya mengembalikan transaksi yang sudah saya lakukan? (Data hilang)