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

Comment puis-je interroger les classements des utilisateurs de ma base de données, mais ne considérer que la dernière entrée pour chaque utilisateur ?

C'est ce que j'appelle le problème du "plus grand-n-par-groupe". Il apparaît plusieurs fois par semaine sur StackOverflow.

Je résous ce type de problème en utilisant une technique de jointure externe :

SELECT s1.*, s1.wins / s1.losses AS win_loss_ratio
FROM Scrape s1
LEFT OUTER JOIN Scrape s2
  ON (s1.username = s2.username AND s1.ScrapeDate < s2.ScrapeDate)
WHERE s2.username IS NULL
ORDER BY win_loss_ratio DESC;

Cela renverra une seule ligne pour chaque nom d'utilisateur -- la ligne avec la plus grande valeur dans ScrapeDate colonne. C'est à cela que sert la jointure externe, pour essayer pour correspondre à s1 avec une autre ligne s2 avec le même nom d'utilisateur et une date supérieure. S'il n'y a pas une telle ligne, la jointure externe renvoie NULL pour toutes les colonnes de s2 , et nous savons alors s1 correspond à la ligne avec la plus grande date pour ce nom d'utilisateur donné.

Cela devrait également fonctionner lorsque vous avez un grattage partiellement terminé en cours.

Cette technique n'est pas nécessairement aussi rapide que les solutions CTE et RANKING que d'autres réponses ont fournies. Vous devriez essayer les deux et voir ce qui fonctionne le mieux pour vous. La raison pour laquelle je préfère ma solution est qu'elle fonctionne dans n'importe quelle version de SQL.