Mudei o nome da sua coluna
group
para grp
porque group
é uma palavra reservada
no Postgres e em todos os padrões SQL e não deve ser usado como identificador. Eu entendo sua pergunta assim:
Obtenha as duas matrizes classificadas em ordem de classificação idêntica para que a mesma posição do elemento corresponda à mesma linha em ambas as matrizes.
Usar uma subconsulta ou CTE e ordene as linhas antes de agregar.
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;
Isso é mais rápido do que usar
ORDER BY
individual cláusulas na função agregada
array_agg()
como @Mosty demonstra
(e que existe desde o PostgreSQL 9.0). Mosty também interpreta sua pergunta de maneira diferente e usa as ferramentas adequadas para sua interpretação. É ORDER BY
em um cofre de subconsulta?
O manual:
Então sim, é seguro no exemplo.
Sem subconsulta
Se você realmente precisa uma solução sem subconsulta , você pode:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
Observe o
ORDER BY grp, dt
. Eu classifico por dt
além de desempate e tornar a ordem de classificação inequívoca. Não é necessário para grp
, no entanto. Há também uma maneira completamente diferente de fazer isso, com funções de janela :
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;
Observe o
DISTINCT ON (id)
em vez de apenas DISTINCT
que produz o mesmo resultado, mas executa mais rápido em uma ordem de magnitude porque não precisamos de uma classificação extra. Fiz alguns testes e isso é quase tão rápido quanto as outras duas soluções. Como esperado, a versão de subconsulta ainda era mais rápida. Teste com
EXPLAIN ANALYZE
para ver por si mesmo.