sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo ordenar objetos en una matriz dentro de un valor json o jsonb por una propiedad de los objetos?

El orden de las claves en un objeto en un jsonb literal es insignificante:las claves de objeto se ordenan internamente de todos modos. (json es diferente en este sentido). Ver:

El orden de los elementos de la matriz en un jsonb (o json ) literal es significativo, sin embargo. Su solicitud es significativa. Puede reordenar así:

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 aquí

Pero sería más eficiente para ordenar la matriz antes asignándolo:

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

Sobre el orden de las filas de una subconsulta

En SQL estándar, el orden de las filas en una subconsulta (o cualquier expresión de tabla) también es insignificante. Pero en Postgres, el orden de las filas en las subconsultas se traslada al siguiente nivel. Entonces esto funciona en consultas simples. Incluso está documentado :

Si no puede o no quiere confiar en esto, existe una alternativa segura:agregue un ORDER BY a la propia función agregada. Eso es aún más corto:

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

Pero normalmente es más lento .