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

Comment trier les objets dans un tableau à l'intérieur d'une valeur json ou jsonb par une propriété des objets ?

L'ordre des clés dans un objet dans un jsonb le littéral est insignifiant - les clés d'objet sont de toute façon triées en interne. (json est différent à cet égard.) Voir :

L'ordre des éléments du tableau dans un jsonb (ou json ) littéral est significatif, cependant. Votre demande est significative. Vous pouvez réorganiser comme ceci :

SELECT jsonb_agg(elem)
FROM  (
   SELECT *
   FROM   jsonb_array_elements(v_combined) a(elem)
   ORDER  BY (elem->>'ts')::int  -- order by integer value of "ts"
   ) sub;

dbfiddle ici

Mais ce serait plus efficace pour commander le tableau avant en l'attribuant :

...
DECLARE
   v_combined      jsonb;
BEGIN
   SELECT INTO v_combined  jsonb_agg(elem)
   FROM  (
      SELECT ts, json_agg(data_table_1) AS j
      FROM   data_table_1
      WHERE  fk_id = v_id

      UNION ALL 
      SELECT ts, json_agg(data_table_2)
      FROM   data_table_2
      WHERE  fk_id = v_id
      ORDER  BY ts
      ) sub;
...

Sur l'ordre des lignes d'une sous-requête

En SQL standard, l'ordre des lignes dans une sous-requête (ou toute expression de table) est également insignifiante. Mais dans Postgres, l'ordre des lignes dans les sous-requêtes est reporté au niveau suivant. Cela fonctionne donc dans des requêtes simples. C'est même documenté :

Si vous ne pouvez pas ou ne voulez pas vous y fier, il existe une alternative sûre :ajoutez un ORDER BY à la fonction d'agrégation elle-même. C'est encore plus court :

SELECT INTO v_combined  jsonb_agg(elem  ORDER BY (elem->>'ts')::int)
FROM   jsonb_array_elements(v_combined) a(elem);

Mais c'est généralement plus lent .