J'ai une table mysql comme ci-dessous:
id name points 1 john 4635 3 tom 7364 4 bob 234 6 harry 9857
3 Réponses :
SELECT uo.*, ( SELECT COUNT(DISTINCT ui.points) FROM users ui WHERE ui.points >= uo.points ) AS rank FROM users uo WHERE id = @id
Je l'aime. Un peu de réglage et cela correspond à mes besoins. Merci d'avoir partagé!
Problème mineure: S'il y a des liens, cela retournera le rang le plus élevé plutôt que le plus bas. Si vous voulez le plus bas, changez la condition sur > code> et la valeur sur
comptent (*) + 1 code>.
@Barmar: S'il y a des liens, cela utilisera ID code> comme critère secondaire.
Ahh, n'a pas réalisé que vous pourriez faire une comparaison composée comme celle-là. Bien qu'il semble arbitraire qu'un joueur soit mieux classé, simplement parce qu'ils ont un identifiant supérieur. Tout le monde dans une cravate devrait avoir le même rang.
@Barmar: Pour émuler dense_rank code> (c'est ce dont vous parlez) il suffit de remplacer
comptez (*) code> avec
compteur (points distincts) code>
Cela fusionnera des liens devant vous aussi. Si les scores sont 10, 9, 9, 8, 8, les rangs doivent être de 1, 2, 2, 4, 4 (ou, plus spécifiquement, 1, 2-3, 2-3, 4-5, 4-5 ).
@Barmar: Il existe trois fonctions de fenêtre pour le classement: Row_Number code> (ma requête d'origine),
(code> (votre commentaire précédent) et
dense_rank code> (mon précédent commenter). Comme ils existent tous et sont utilisés, je n'utiliserais pas «devrait» sans connaître les intentions exactes de l'OP.
Je pense que la manière dont les classements dans un jeu sont généralement déclarés sont la façon dont j'ai décrit. Ils rapporteront quelque chose comme "liés pour la 4ème et la 5ème place". S'il y a une cravate pour la 1ère place, le joueur après qu'ils obtiennent la 3ème place, pas 2e.
@Quassnoi vous semblez comprendre cela beaucoup mieux que la plupart des utilisateurs, un travail fantastique!
Solution de @Quassnoi échouera en cas de cravates. Voici la solution qui fonctionnera en cas de cravates:
À noter, le rang sera 0 si la première place a un score de 0. En outre, en cas de cravates, le rang est incrémenté, non ignoré par ex. 10 - 1er 9 - 2e, 9 - 2e, 6 - 3ème. De plus, la récupération des rangées devrait être dans une sous-requête, car la commande est appliquée après le classement.
SET @rownum := 0; SELECT rank, score FROM ( SELECT @rownum := @rownum +1 AS rank, `score` ,`user_id` FROM leaderboard ORDER BY `score` DESC , `updated_timestamp` ) as result WHERE `user_id`=$user_id LIMIT 1