PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Crie dois arrays para dois campos, mantendo a ordem de classificação dos arrays em sincronia (sem subconsulta)


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.