PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Przekazywanie tablicy tablic jako parametru do funkcji

Podoba mi się twoje drugie podejście.

SELECT DISTINCT t.*
FROM   (VALUES (1, 4), (5, 1), (2, 3), (1, 4), (7, 3), (7, 4)) AS t(a, b)
JOIN   (
   SELECT arr[1]::int[] AS a1
         ,arr[2]::int[] AS b1
   FROM   (
      SELECT unnest(ARRAY['{"{1,2}", "{3,4}"}'
                         ,'{"{}"   , "{4,5,6}"}'
                         ,'{"{5}"  , "{}"}'    -- added element to 1st dimension
                         ])::text[] AS arr     -- 1d text array
      ) sub
   ) s ON (a = ANY(a1) OR a1 = '{}')
      AND (b = ANY(b1) OR b1 = '{}')
;

Proponowanie tylko drobnych ulepszeń:

  1. Podzapytania zamiast CTE dla nieco lepszej wydajności.

  2. Uproszczony test dla pustej tablicy:sprawdzanie względem literału '{}' zamiast wywołania funkcji.

  3. Jeden poziom podzapytania mniej do rozpakowania tablicy.

Wynik:

a | b
--+---
2 | 3
7 | 4
1 | 4
5 | 1

Dla zwykłego czytelnika:Zawijanie wielowymiarowej tablicy liczb całkowitych jest konieczne, ponieważ Postgres tego wymaga (cytując komunikat o błędzie):

trasa alternatywna byłby z dwuwymiarową tablicą tekstową i rozpakuj go za pomocą generate_subscripts() :

WITH a(arr) AS (SELECT '{{"{1,2}", "{3,4}"}
                        ,{"{}", "{4,5,6}"}
                        ,{"{5}", "{}"}}'::text[]   -- 2d text array
             )
SELECT DISTINCT t.*
FROM  (VALUES (1, 4), (5, 1), (2, 3), (1, 4), (7, 3), (7, 4)) AS t(a, b)
JOIN  (
   SELECT arr[i][1]::int[] AS a1
         ,arr[i][2]::int[] AS b1
   FROM   a, generate_subscripts(a.arr, 1) i       -- using implicit LATERAL
   ) s ON (t.a = ANY(s.a1) OR s.a1 = '{}')
      AND (t.b = ANY(s.b1) OR s.b1 = '{}');

Może być szybciej, czy możesz przetestować?

W wersjach wcześniejszych niż 9.3 należałoby użyć jawnego CROSS JOIN zamiast poprzecznego łączenia krzyżowego.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rails 4 Postgresql array-type:aktualizacja wartości

  2. heroku pg:uwierzytelnianie hasła pull nie powiodło się

  3. SQLAlchemy, Declarative, PostgreSQL:nie można tworzyć tabel

  4. Cofanie alokacji przygotowanych zapytań

  5. Barman 2.11:barman-cloud-restore i barman-cloud-wal-restore