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

Como classificar objetos em um array dentro de um valor json ou jsonb por uma propriedade dos objetos?


A ordem das chaves em um objeto em um jsonb literal é insignificante - as chaves de objeto são classificadas internamente de qualquer maneira. (json é diferente a este respeito.) Veja:

A ordem dos elementos da matriz em um jsonb (ou json ) literal é significativo, no entanto. Seu pedido é significativo. Você pode reordenar assim:
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 aqui

Mas seria mais eficiente para ordenar o array antes atribuindo-o:
...
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;
...

Na ordem das linhas de uma subconsulta


No SQL padrão, a ordem das linhas em uma subconsulta (ou qualquer expressão de tabela) também é insignificante. Mas no Postgres a ordem das linhas nas subconsultas é transportada para o próximo nível. Portanto, isso funciona em consultas simples. Está até documentado :

Se você não pode ou não vai confiar nisso, existe uma alternativa segura:adicione um ORDER BY para a própria função agregada. Isso é ainda mais curto:
SELECT INTO v_combined  jsonb_agg(elem  ORDER BY (elem->>'ts')::int)
FROM   jsonb_array_elements(v_combined) a(elem);

Mas normalmente é mais lento .