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

PostgreSQL DISTINCT ON avec ORDER BY différent

La documentation indique :

DISTINCT ON ( expression [, ...] ) ne conserve que la première ligne de chaque ensemble de lignes où les expressions données sont égales. [...] Notez que la "première ligne" de chaque ensemble est imprévisible sauf si ORDER BY est utilisé pour s'assurer que la ligne souhaitée apparaît en premier. [...] La ou les expressions DISTINCT ON doivent correspondre à la ou aux expressions ORDER BY les plus à gauche.

Documents officiels

Vous devrez donc ajouter le address_id à la commande par.

Sinon, si vous recherchez la ligne complète contenant le produit acheté le plus récemment pour chaque address_id et ce résultat trié par purchased_at alors vous essayez de résoudre un plus grand problème N par groupe qui peut être résolu par les approches suivantes :

La solution générale qui devrait fonctionner dans la plupart des SGBD :

SELECT t1.* FROM purchases t1
JOIN (
    SELECT address_id, max(purchased_at) max_purchased_at
    FROM purchases
    WHERE product_id = 1
    GROUP BY address_id
) t2
ON t1.address_id = t2.address_id AND t1.purchased_at = t2.max_purchased_at
ORDER BY t1.purchased_at DESC

Une solution plus orientée PostgreSQL basée sur la réponse de @hkf :

SELECT * FROM (
  SELECT DISTINCT ON (address_id) *
  FROM purchases 
  WHERE product_id = 1
  ORDER BY address_id, purchased_at DESC
) t
ORDER BY purchased_at DESC

Problème clarifié, étendu et résolu ici :Sélection de lignes ordonnées par une colonne et distinctes sur une autre