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

Обединяване на масиви в група по клауза

UNION ALL

Бихте могли да "контра-въртите" с UNION ALL първо:

SELECT name, array_agg(c) AS c_arr
FROM  (
   SELECT name, id, 1 AS rnk, col1 AS c FROM tbl
   UNION ALL
   SELECT name, id, 2, col2 FROM tbl
   ORDER  BY name, id, rnk
   ) sub
GROUP  BY 1;

Адаптиран за създаване на реда на стойностите, които сте поискали по-късно. Ръководството:

Удебелен акцент е мой.

LATERAL подзаявка с VALUES израз

LATERAL изисква Postgres 9.3 или по-късно.

SELECT t.name, array_agg(c) AS c_arr
FROM  (SELECT * FROM tbl ORDER BY name, id) t
CROSS  JOIN LATERAL (VALUES (t.col1), (t.col2)) v(c)
GROUP  BY 1;

Същият резултат. Нуждае се само от едно минаване над масата.

Персонализирана агрегатна функция

Или можете да създадете персонализирана агрегатна функция, както е обсъдено в тези свързани отговори:

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

След това можете:

SELECT name, array_agg_mult(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM   tbl
GROUP  BY 1
ORDER  BY 1;

Или обикновено по-бързо, но не е стандартен SQL:

SELECT name, array_agg_mult(ARRAY[col1, col2]) AS c_arr
FROM  (SELECT * FROM tbl ORDER BY name, id) t
GROUP  BY 1;

Добавеният ORDER BY id (който може да бъде добавен към такива агрегатни функции) гарантира желания резултат:

a | {1,2,3,4}
b | {5,6,7,8}

Или може да се интересувате от тази алтернатива:

SELECT name, array_agg_mult(ARRAY[ARRAY[col1, col2]] ORDER BY id) AS c_arr
FROM   tbl
GROUP  BY 1
ORDER  BY 1;

Което създава двумерни масиви:

a | {{1,2},{3,4}}
b | {{5,6},{7,8}}

Последният може да бъде заменен (и трябва да бъде, тъй като е по-бърз!) с вградения array_agg() в Postgres 9.5 или по-късно - с добавената възможност за агрегиране на масиви:

SELECT name, array_agg(ARRAY[col1, col2] ORDER BY id) AS c_arr
FROM   tbl
GROUP  BY 1
ORDER  BY 1;

Същият резултат. Ръководството:

Така че не е точно същото като нашата персонализирана агрегатна функция array_agg_mult();



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. org.postgresql.util.PSQLException:ФАТАЛНО:съжалявам, твърде много клиенти вече

  2. ФАТАЛНО:удостоверяването на паролата не бе успешно за потребител postgres (postgresql 11 с pgAdmin 4)

  3. Формат на времето на Rails Activerecord/Postgres

  4. PostgreSQL UPDATE замяна на подниз

  5. Връзка много към много, за да се определи дали потребителят е харесал публикация