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.