PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come ordinare gli oggetti in un array all'interno di un valore json o jsonb in base a una proprietà degli oggetti?

L'ordine delle chiavi in ​​un oggetto in un jsonb letterale è insignificante - le chiavi degli oggetti sono comunque ordinate internamente. (json è diverso al riguardo.) Vedi:

L'ordine degli elementi dell'array in un jsonb (o json ) letterale è significativo, però. La tua richiesta è significativa. Puoi riordinare in questo modo:

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 qui

Ma sarebbe più efficiente per ordinare l'array prima assegnandolo:

...
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;
...

Sull'ordine delle righe da una sottoquery

In SQL standard l'ordine delle righe anche in una sottoquery (o qualsiasi espressione di tabella) è insignificante. Ma in Postgres l'ordine delle righe nelle sottoquery viene riportato al livello successivo. Quindi funziona con query semplici. È persino documentato :

Se non puoi o non vuoi fare affidamento su questo, c'è un'alternativa sicura:aggiungi un ORDER BY alla funzione aggregata stessa. È ancora più breve:

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

Ma in genere è più lento .