PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Crea due array per due campi, mantenendo sincronizzato l'ordinamento degli array (senza subquery)

Ho cambiato il nome della colonna group a grp perché group è una parola riservata in Postgres e in ogni standard SQL e non dovrebbe essere usato come identificatore.

Capisco la tua domanda in questo modo:

Ottieni i due array ordinati in modo identico in modo che la stessa posizione dell'elemento corrisponda alla stessa riga in entrambi gli array.

Utilizza una sottoquery o CTE e ordina le righe prima di aggregare.

SELECT id, array_agg(grp) AS grp, array_agg(dt) AS dt
FROM  (
    SELECT *
    FROM   tbl
    ORDER  BY id, grp, dt
    ) x
GROUP  BY id;

È più veloce piuttosto che utilizzare ORDER BY clausole nella funzione aggregata array_agg() come @Mosty dimostra (e che esiste da PostgreSQL 9.0). Mosty interpreta anche la tua domanda in modo diverso e usa gli strumenti adeguati per la sua interpretazione.

È ORDER BY in una cassaforte per sottoquery?

Il manuale:

Quindi sì, è sicuro nell'esempio.

Senza sottoquery

Se ne hai veramente necessità una soluzione senza subquery , puoi:

SELECT id
     , array_agg(grp ORDER BY grp)
     , array_agg(dt  ORDER BY grp, dt)
FROM   tbl
GROUP  BY id;

Nota il ORDER BY grp, dt . Ordino per dt oltre a rompere i legami e rendere inequivocabile l'ordinamento. Non necessario per grp , però.

C'è anche un modo completamente diverso per farlo, con funzioni della finestra :

SELECT DISTINCT ON (id)
       id
     , array_agg(grp) OVER w AS grp
     , array_agg(dt)  OVER w AS dt
FROM   tbl
WINDOW w AS (PARTITION BY id ORDER BY grp, dt
             ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER  BY id;

Nota il DISTINCT ON (id) anziché solo DISTINCT che produce lo stesso risultato ma si comporta più velocemente di un ordine di grandezza perché non abbiamo bisogno di un ordinamento aggiuntivo.

Ho eseguito alcuni test e questo è quasi veloce quanto le altre due soluzioni. Come previsto, la versione subquery era ancora più veloce. Prova con EXPLAIN ANALYZE da vedere di persona.