web-dev-qa-db-fra.com

Sélectionner les enregistrements en fonction de la dernière date

Basé sur la table appelée Course ci-dessous:

enter image description here

Comment puis-je sélectionner les enregistrements dont le nom du cours porte la date la plus récente? Je veux dire que si j'ai deux noms de cours identiques pour un ID, je ne devrais afficher que le dernier en tant que résultat ci-dessous.

Simplement, je veux seulement afficher la dernière ligne par ("ID", "Nom du cours").

enter image description here

Et si j'ai deux colonnes de date dans la table Course, qui sont StartDate & EndDate et que je souhaite afficher la même chose en fonction de EndDate uniquement?

J'utilise PostgreSQL.

12
Aan

Dans PostgreSQL, pour obtenir des lignes uniques pour un ensemble défini de colonnes , la technique préférable est généralement/ DISTINCT ON :

SELECT DISTINCT ON ("ID") *
FROM   "Course"
ORDER  BY "ID", "Course Date" DESC NULLS LAST, "Course Name";

En supposant que vous utilisiez réellement ces identificateurs majuscules malheureux avec des espaces.

Vous obtenez exactement une ligne par ID de cette façon - celle avec le dernier "Course Date" connu et le premier "Course Name" (selon l’ordre de tri) en cas d’égalité à la date.

Vous pouvez supprimer NULLS LAST si votre colonne est définie NOT NULL.

Pour obtenir des lignes uniques par ("ID", "Course Name"):

SELECT DISTINCT ON ("ID", "Course Name") *
FROM   "Course"
ORDER  BY "ID", "Course Name", "Course Date" DESC NULLS LAST;

Détails dans cette réponse:

20
Erwin Brandstetter
SELECT *
FROM (SELECT ID, CourseName, CourseDate, 
      MAX(CourseDate) OVER (PARTITION BY COURSENAME) as MaxCourseDate
FROM Course) x
WHERE CourseDate = MaxCourseDate

Ici, le MAX () OVER (PARTITION BY) vous permet de trouver la date de cours la plus élevée pour chaque cours (la partition) dans une table dérivée. Ensuite, vous pouvez simplement sélectionner les lignes pour lesquelles CourseDate est égal au maximum de Coursedate trouvé pour ce cours. 

Cette approche présente l'avantage de ne pas utiliser de clause GROUP BY, ce qui limiterait les colonnes que vous pouvez renvoyer, car toute colonne non agrégée de la clause SELECT devrait également figurer dans la clause GROUP BY.

3
GVIrish
SELECT "ID", "Course Name", MAX("Course Date") FROM "Course" GROUP BY "ID", "Course Name"
3
Maxim Krizhanovsky

Essaye ça:

SELECT DISTINCT ON (c."Id", c."Course Name") 
    c."Id", c."Course Name", c."Course Date" 
FROM (SELECT * FROM "Course" ORDER BY "Course Date" DESC) c;
0
Minoru