Změnil jsem název vašeho sloupce group na grp protože group je rezervované slovo
v Postgresu a každém standardu SQL a neměl by být používán jako identifikátor.
Rozumím vaší otázce takto:
Seřaďte dvě pole ve stejném pořadí, aby stejná pozice prvku odpovídala stejnému řádku v obou polích.
Použijte dílčí dotaz nebo CTE a pořadí řádků před agregací.
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;
To je rychlejší než použít jednotlivé ORDER BY klauzule v agregační funkci
array_agg() jako @Mosty předvádí
(a který je tam od PostgreSQL 9.0). Mosty také interpretuje vaši otázku odlišně a používá pro svou interpretaci správné nástroje.
Je ORDER BY v trezoru poddotazu?
Takže ano, v tomto příkladu je to bezpečné.
Bez dílčího dotazu
Pokud opravdu potřebujete řešení bez poddotazu , můžete:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
Všimněte si ORDER BY grp, dt . Třídím podle dt kromě toho přerušit vazby a učinit pořadí řazení jednoznačným. Není nutné pro grp , ačkoli.
Existuje také zcela jiný způsob, jak toho dosáhnout, pomocí funkcí oken :
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;
Všimněte si DISTINCT ON (id) namísto pouhého DISTINCT který poskytuje stejný výsledek, ale funguje o řád rychleji, protože nepotřebujeme další řazení.
Provedl jsem několik testů a toto je téměř stejně rychlé jako další dvě řešení. Verze poddotazu byla podle očekávání stále nejrychlejší. Otestujte pomocí EXPLAIN ANALYZE přesvědčte se sami.