PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Besoin d'optimisation SQL (peut-être DISTINCT ON est la raison ?)

Fonction d'agrégation pour les tableaux multidimensionnels

Je suppose que vous créez un tableau à deux dimensions pour ça. C'est plus facile à gérer qu'un ARRAY of record . Norme array_agg() ne peut pas agréger des tableaux multidimensionnels. Mais vous pouvez écrire votre propre fonction d'agrégation assez facilement pour cela :

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

Lisez l'explication dans cette réponse connexe :
Sélectionner des données dans un tableau Postgres

Requête

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();
  • Sous-requête x obtient anchor_id distinct par (p, groundtruth) et sélectionne une ligne au hasard s'il y a plusieurs pairs. De cette façon, la connexion anchor_id - id reste intact.

  • La requête externe agrège un tableau à 2 dimensions comme vous le souhaitiez, classé par anchor_id . Si vous voulez avoir anchor_id commandé au hasard, utilisez aléatoire une fois de plus :

    array_agg_mult(ARRAY[ARRAY[anchor_id, id]] ORDER BY random())
    
  • Et enfin, le DISTINCT ON ne choisit qu'une seule groundtruth par p , de nouveau au hasard.