103 votes

Comment sélectionner l'identifiant avec la date maximale en groupant par catégorie dans PostgreSQL ?

Par exemple, je voudrais sélectionner l'identifiant avec la date maximale en le regroupant par catégorie, le résultat est : 7, 2, 6

id  category  date
1   a         2013-01-01
2   b         2013-01-03
3   c         2013-01-02
4   a         2013-01-02
5   b         2013-01-02
6   c         2013-01-03
7   a         2013-01-03
8   b         2013-01-01
9   c         2013-01-01

Puis-je savoir comment faire cela dans PostgreSQL ?

169voto

Erwin Brandstetter Points 110228

C'est un cas d'utilisation parfait pour DISTINCT ON - une extension spécifique à Postgres de la norme DISTINCT :

SELECT DISTINCT ON (category)
       id  -- , category, date  -- any other column (expression) from the same row
FROM   tbl
ORDER  BY category, date DESC;

Attention à l'ordre de tri descendant. Si la colonne peut être NULL, vous pouvez ajouter NULLS LAST :

DISTINCT ON est simple et rapide. Une explication détaillée dans cette réponse connexe :

Pour les grandes tables avec de nombreuses lignes par category envisager une autre approche :

23voto

hims056 Points 13538

Essaie celle-là :

SELECT t1.* FROM Table1 t1
JOIN 
(
   SELECT category, MAX(date) AS MAXDATE
   FROM Table1
   GROUP BY category
) t2
ON T1.category = t2.category
AND t1.date = t2.MAXDATE

Voir ce SQLFiddle

16voto

Craig Ringer Points 72371

Une autre approche consiste à utiliser le first_value fonction de fenêtre : http://sqlfiddle.com/#!12/7a145/14

SELECT DISTINCT
  first_value("id") OVER (PARTITION BY "category" ORDER BY "date" DESC) 
FROM Table1
ORDER BY 1;

... bien que je pense que la suggestion de hims056 sera généralement plus performante lorsque les index appropriés sont présents.

Il existe une troisième solution :

SELECT
  id
FROM (
  SELECT
    id,
    row_number() OVER (PARTITION BY "category" ORDER BY "date" DESC) AS rownum
  FROM Table1
) x
WHERE rownum = 1;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X