PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Предаване на масив от масиви като параметър на функция

Харесвам втория ви подход.

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 = '{}')
;

Предлага само незначителни подобрения:

  1. Подзаявки вместо CTE за малко по-добра производителност.

  2. Опростен тест за празен масив:проверка спрямо литерал '{}' вместо извикване на функция.

  3. Едно ниво на подзаявка по-малко за разопаковане на масива.

Резултат:

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

За случайния читател:Обвиването на многомерния масив от цели числа е необходимо, тъй като Postgres изисква това (цитирайки съобщение за грешка):

Алтернативен маршрут ще бъде с двуизмерен текстов масив и го разместете с помощта на 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 = '{}');

Може да е по-бързо, можете ли да тествате?

Във версии преди 9.3 ще се използва изричен CROSS JOIN вместо странично напречно съединяване.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. hibernate не можа да получи следващата стойност на последователността

  2. PostgreSQL:възможно ли е да предоставите потребителско име за PRIMARY KEY или UNIQUE?

  3. Връщане на групиран списък с поява с помощта на Rails и PostgreSQL

  4. Регистрирайте и стартирайте PostgreSQL 9.0 като Windows Service

  5. Как да оценим израза в оператора select в Postgres