sql >> Databasteknik >  >> RDS >> PostgreSQL

Sammanfoga arrayer inom grupp för klausul

UNION ALL

Du kan "motpivota" med UNION ALL först:

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;

Anpassad för att producera den värdeordning du senare efterfrågade. Manualen:

Djärv betoning min.

LATERAL underfråga med VALUES uttryck

LATERAL kräver Postgres 9.3 eller senare.

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;

Samma resultat. Behöver bara en gång över bordet.

Anpassad aggregatfunktion

Eller du kan skapa en anpassad aggregatfunktion som diskuteras i dessa relaterade svar:

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

Då kan du:

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

Eller, vanligtvis snabbare, men inte standard SQL:

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

Det tillagda ORDER BY id (som kan läggas till sådana samlade funktioner) garanterar ditt önskade resultat:

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

Eller så kanske du är intresserad av detta alternativ:

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

Som producerar 2-dimensionella arrayer:

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

Den sista kan ersättas (och borde vara det, eftersom den är snabbare!) med den inbyggda array_agg() i Postgres 9.5 eller senare - med dess extra förmåga att aggregera arrayer:

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

Samma resultat. Manualen:

Så inte exakt samma som vår anpassade aggregatfunktion array_agg_mult();



  1. Få datum mellan två datum

  2. CakePHP 3.5 Använd alltid asText() MySQL-funktionen på Spatial field

  3. mysql ersätt text i ett fält php

  4. HikariCP med PostgreSQL:setQueryTimeout(int) är ännu inte implementerat