Cambié el nombre de tu columna group
a grp
porque group
es una palabra reservada
en Postgres y todos los estándares SQL y no debe usarse como identificador.
Entiendo tu pregunta así:
Obtenga las dos matrices ordenadas en el mismo orden de clasificación para que la misma posición del elemento corresponda a la misma fila en ambas matrices.
Usar una subconsulta o CTE y ordene las filas 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;
Eso es más rápido que usar ORDER BY
cláusulas en la función agregada
array_agg()
como @Mosty demuestra
(y que ha estado allí desde PostgreSQL 9.0). Mosty también interpreta tu pregunta de manera diferente y utiliza las herramientas adecuadas para su interpretación.
Es ORDER BY
en una subconsulta segura?
Así que sí, es seguro en el ejemplo.
Sin subconsulta
Si realmente necesitas una solución sin subconsulta , puedes:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
Tenga en cuenta el ORDER BY grp, dt
. Ordeno por dt
además de romper los lazos y hacer que el orden de clasificación sea inequívoco. No es necesario para grp
, sin embargo.
También hay una forma completamente diferente de hacer esto, con funciones de ventana :
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;
Tenga en cuenta el DISTINCT ON (id)
en lugar de solo DISTINCT
que produce el mismo resultado pero funciona más rápido en un orden de magnitud porque no necesitamos una ordenación adicional.
Realicé algunas pruebas y esto es casi tan rápido como las otras dos soluciones. Como era de esperar, la versión de subconsulta seguía siendo la más rápida. Prueba con EXPLAIN ANALYZE
para verlo por ti mismo.