Je vois beaucoup de gens l'utilisation de sous-requêtes ou autre fournisseur de fonctionnalités spécifiques pour ce faire, mais je fais souvent ce genre de requête sans les sous-requêtes de la manière suivante. Il utilise la plaine, le standard SQL, donc il devrait fonctionner dans tous les SGBD.
SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
ON (t1.UserId = t2.UserId AND t1."Date" < t2."Date")
WHERE t2.UserId IS NULL;
En d'autres termes: extraction de la ligne de t1 où aucune autre ligne existe avec le même nom d'utilisateur et un plus grand Jour.
(J'ai mis de l'identificateur de type "Date" dans les délimiteurs parce que c'est un mot réservé SQL.)
Dans le cas où si t1."Date" = t2."Date", en doublant apparaît. Généralement, les tables a auto_inc(seq), par exemple, Id.
Pour éviter de doubler peut être utilisée suit:
SELECT t1.*
FROM mytable t1
LEFT OUTER JOIN mytable t2
ON t1.UserId = t2.UserId AND ((t1."Date" < t2."Date")
OR (t1."Date" = t2."Date" AND t1.id < t2.id))
WHERE t2.UserId IS NULL;
Re commentaire de @Farhan:
Voici une explication plus détaillée:
Une jointure externe tente de rejoindre t1 avec t2. Par défaut, tous les résultats de t1 sont retournés, et si il y a un match en t2, il est également renvoyé. Si il n'y a pas de correspondance dans la t2 pour une ligne donnée de t1, la requête renvoie toujours la ligne de t1, et NULL est utilisé comme un espace réservé pour tous les t2 colonnes. C'est juste la façon dont les jointures externes travail en général.
L'astuce de cette requête est la conception de la jointure de la condition de correspondance tel que t2 doit correspondre à la même nom d'utilisateur, et une grande date. L'idée étant, si une ligne existe en t2 qui a plus de date, puis la ligne t1 c'est comparée ne peut pas être la plus grande date pour ce nom d'utilisateur. Mais si il n'y a pas de correspondance -- c'est à dire si aucune ligne n'existe en t2 avec un plus grand jour que la ligne t1-nous savons que la ligne t1 a été la ligne avec la plus grande date pour le nom d'utilisateur.
Dans ces cas (quand il n'y a pas de match), les colonnes de t2 sera NULLE, même les colonnes spécifiées dans la condition de jointure. C'est pourquoi nous utilisons WHERE t2.UserId IS NULL
, parce que nous sommes à la recherche pour les cas où aucune ligne n'a été trouvé avec une grande date pour le nom d'utilisateur.