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

Начален масив във функция за агрегиране на многоизмерен масив

Postgres 9.5 или по-нова версия

... се доставя с допълнителен вариант на агрегатната функция array_agg() . Ръководството:

входни масиви, конкатенирани в масив с едно по-високо измерение (всички входове трябва да имат еднаква размерност и не могат да бъдат празни или нулеви)

Така че не е точно същото като персонализираната агрегатна функция array_agg_mult() По-долу. Но използвайте го, ако можете. По-бързо е.

Свързано:

  • Как да сортирам двуизмерен int масив в PostgreSQL?

Postgres 9.4 или по-стара версия

Обобщаваща функция за всякак тип масив

С полиморфния тип anyarray работи за всички видове масиви (включително integer[] ):

CREATE AGGREGATE array_agg_mult (anyarray) (
   SFUNC     = array_cat
 , STYPE     = anyarray
 , INITCOND  = '{}'
);

Както @Lukas предостави, персонализираната функция arrayappend() не е необходимо. Вграденият array_cat() върши работата. Това обаче не обяснява защо вашият пример се проваля, докато този в отговора на Лукас работи. Съответната разлика е, че Лукас е вложил масива в друг слой масив с array[d.a] .

Препъвате се в неправилното предположение, че бихте могли да декларирате тип int[][] . Но не можете:int[][] е от същия тип като int[] за системата тип PostgreSQL. Главата за типовете масиви в ръководството обяснява:

Текущата реализация също не налага декларирания брой измерения. Масивите от конкретен тип елемент се считат за от един и същи тип, независимо от размера или броя на измеренията. И така, деклариране на размера на масива или броя на измеренията вCREATE TABLE е просто документация; това не влияе на поведението по време на изпълнение.

n -дименсионалният целочислен масив ефективно е масив от n-1 -размерни масиви от цели числа в PostgreSQL. Не можете да разберете това от типа, който дефинира само базовия елемент . Трябва да попитате array_dims() за да получите подробности.

За демонстрация:

SELECT array_agg_mult(arr1)               AS arr1  --> 1-dim array
     , array_agg_mult(ARRAY[arr1])        AS arr2  --> 2-dim array
     , array_agg_mult(ARRAY[ARRAY[arr1]]) AS arr3  --> 3-dim array
       -- etc.
FROM  (
   VALUES
      ('{1,2,3}'::int[])                           -- 1-dim array
    , ('{4,5,6}')
    , ('{7,8,9}')
   ) t(arr1);

Или:

SELECT array_agg_mult(arr2)        AS arr2  --> 2-dim array
     , array_agg_mult(ARRAY[arr2]) AS arr3  --> 3-dim array
     , array_agg(arr2)             AS arr3  --> 3-dim array; superior in Postgres 9.5+
FROM  (
   VALUES
      ('{{1,2,3}}'::int[])                  -- 2-dim array
     ,('{{4,5,6}}')
     ,('{{7,8,9}}')
   ) t(arr2);

Всички получените колони са от същия тип :int[] (въпреки че съдържа различен брой измерения).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Подаване на име на таблица като параметър в psycopg2

  2. Вмъкване на текст с единични кавички в PostgreSQL

  3. Еквивалент на strftime в Postgres

  4. Как мога да изпратя някаква http заявка от postgresql функция или тригер

  5. Първични ключове с Apache Spark