Comment sélectionner id avec date max groupe par catégorie dans PostgreSQL?

pour un exemple, je voudrais sélectionner id avec max date group 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?

55
demandé sur Erwin Brandstetter 2013-06-04 13:21:01

4 réponses

c'est un étui parfait pour DISTINCT ON (extension spécifique de la norme DISTINCT ):

SELECT DISTINCT ON (category)
       id  -- , category, date -- add 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 nulle, vous pouvez ajouter NULLS LAST :

DISTINCT ON est le plus simple et rapide. Explication détaillée dans cette réponse connexe:

Pour les grandes tables de considérer cette approche alternative:

optimisation des Performances pour les beaucoup lignes par category :

90
répondu Erwin Brandstetter 2018-01-05 11:31:40

essayez celui-ci:

SELECT * 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

15
répondu hims056 2013-06-04 09:25:24

une autre approche consiste à utiliser la fonction de fenêtre first_value : 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 suspecte que la suggestion de hims056 sera typiquement plus performante là où les index appropriés sont présents.

une troisième solution est:

SELECT
  id
FROM (
  SELECT
    id,
    row_number() OVER (PARTITION BY "category" ORDER BY "date" DESC) AS rownum
  FROM Table1
) x
WHERE rownum = 1;
10
répondu Craig Ringer 2013-06-04 12:29:17

SELECT id FROM tbl GROUP BY cat HAVING MAX (date)

-2
répondu Unmerciful 2017-07-27 09:56:59