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

Necesita optimización de SQL (¿tal vez DISTINCT ON es el motivo?)

Función agregada para arreglos multidimensionales

Supongo que creas una matriz bidimensional para eso. Eso es más fácil de manejar que un ARRAY of record . Estándar array_agg() no puede agregar matrices multidimensionales. Pero puede escribir su propia función agregada con bastante facilidad para eso:

CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
   ,STYPE     = anyarray
   ,INITCOND  = '{}'
);

Lea la explicación en esta respuesta relacionada:
Selección de datos en una matriz de Postgres

Consulta

SELECT DISTINCT ON (p)
       p, groundtruth, array_agg_mult(ARRAY[ARRAY[anchor_id, id]]) AS ids
FROM (
   SELECT DISTINCT ON (ps.p, m.groundtruth, m.anchor_id)
          ps.p, m.groundtruth, m.anchor_id, m.id
   FROM  (SELECT unnest(point_array) AS p) AS ps
   JOIN   measurement m ON ST_DWithin(ps.p, m.groundtruth, distance)
   ORDER  BY ps.p, m.groundtruth, m.anchor_id, random()
   ) x
GROUP  BY p, groundtruth
ORDER  BY p, random();
  • Subconsulta x obtiene distinto anchor_id por (p, groundtruth) y elige una fila aleatoria si hay varios pares. De esta forma la conexión anchor_id - id permanece intacto.

  • La consulta externa agrega una matriz bidimensional como la que deseabas, ordenada por anchor_id . Si quieres tener anchor_id ordenado al azar, usa aleatorio una vez más:

    array_agg_mult(ARRAY[ARRAY[anchor_id, id]] ORDER BY random())
    
  • Y finalmente, el DISTINCT ON elige solo 1 groundtruth por p , al azar de nuevo.