PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Créez deux tableaux pour deux champs, en gardant l'ordre de tri des tableaux synchronisé (sans sous-requête)

J'ai changé le nom de votre colonne group à grp car group est un mot réservé dans Postgres et dans tous les standards SQL et ne doit pas être utilisé comme identifiant.

Je comprends votre question comme suit :

Obtenir les deux tableaux triés dans un ordre de tri identique afin que la même position d'élément corresponde à la même ligne dans les deux tableaux.

Utiliser une sous-requête ou CTE et triez les lignes avant de les agréger.

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;

C'est plus rapide que d'utiliser un ORDER BY clauses dans la fonction d'agrégation array_agg() comme @Mosty démontre (et qui existe depuis PostgreSQL 9.0). Mosty interprète également votre question différemment et utilise les outils appropriés pour son interprétation.

Est ORDER BY dans un coffre-fort de sous-requêtes ?

Le manuel :

Donc oui, c'est sûr dans l'exemple.

Sans sous-requête

Si vous avez vraiment besoin une solution sans sous-requête , vous pouvez :

SELECT id
     , array_agg(grp ORDER BY grp)
     , array_agg(dt  ORDER BY grp, dt)
FROM   tbl
GROUP  BY id;

Notez le ORDER BY grp, dt . Je trie par dt en plus de rompre les liens et de rendre l'ordre de tri sans ambiguïté. Pas nécessaire pour grp , cependant.

Il existe également une manière complètement différente de procéder, avec les fonctions de fenêtre :

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;

Notez le DISTINCT ON (id) au lieu de simplement DISTINCT qui produit le même résultat mais s'exécute plus rapidement d'un ordre de grandeur car nous n'avons pas besoin d'un tri supplémentaire.

J'ai fait quelques tests et c'est presque aussi rapide que les deux autres solutions. Comme prévu, la version de la sous-requête était toujours la plus rapide. Testez avec EXPLAIN ANALYZE à voir par vous-même.