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

Precisa de otimização SQL (talvez DISTINCT ON seja o motivo?)

Função agregada para arrays multidimensionais


Suponho que você crie um matriz bidimensional por isso. Isso é mais fácil de lidar do que um ARRAY of record . Padrão array_agg() não pode agregar matrizes multidimensionais. Mas você pode escrever sua própria função agregada com bastante facilidade para isso:
CREATE AGGREGATE array_agg_mult (anyarray)  (
    SFUNC     = array_cat
   ,STYPE     = anyarray
   ,INITCOND  = '{}'
);

Leia a explicação nesta resposta relacionada:
Selecionando dados em uma matriz 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 obtém anchor_id distinto por (p, groundtruth) e escolhe uma linha aleatória se houver vários pares. Desta forma a conexão anchor_id - id permanece intacto.

  • A consulta externa agrega um array bidimensional como você deseja, ordenado por anchor_id . Se você deseja ter anchor_id ordenado aleatoriamente, use random mais uma vez:
    array_agg_mult(ARRAY[ARRAY[anchor_id, id]] ORDER BY random())
    

  • E, finalmente, o DISTINCT ON escolhe apenas 1 groundtruth por p , aleatoriamente novamente.