在Django ORM或SQL中排名?

5 投票
3 回答
4185 浏览
提问于 2025-04-15 18:30

我有一个很大的列表,里面的内容是根据不同的值进行排名的(比如分数)

所以我抓取了这个按这些值排序的列表:

players = Player.objects.order_by('-score', '-karma')

我想要做的是:

  • 找到一个玩家,并获取他的邻近玩家

P1 分数:123

P2 分数:122

!分数:110

P3 分数:90

P2 分数:89

  • 获取排名

你的分数排名是 #1234

你的 karma 排名是 #9876


非常感谢你的帮助。谢谢 :)

3 个回答

0

我用ORM做了三个查询,但我觉得查询的数量少一些会更好:

user_rank = Score.objects.filter(high_score__gt=user_score.high_score).count() + 1

neighbour_scores = Score.objects.filter(game_id=gme,~Q(user_id = usr),high_score__gte=user_score.high_score).order_by('high_score')[:offset]
neighbour_scores.append(user_score)
neighbour_scores.append(Score.objects.filter(game_id=gme, high_score__lt=user_score.high_score).order_by('-high_score')[:offset])
9

这种事情总是很难处理。你需要为每一个情况进行多次查询。

所以,要获取在你得分位置前后紧挨的玩家,首先你得弄清楚你的得分位置是多少。(注意,这里假设不会有两个玩家得分相同,但实际上这不一定成立。)

me = Player.objects.get(pk=my_pk)
position = Players.objects.all().filter(
                            score__lte=me.score).order_by('-score').count()

players = Players.objects.all()[position-2:position+2]
2

要获取用户的排名:

(SELECT * FROM (
  SELECT
    RANK() OVER (ORDER BY Score desc ,Karma desc) AS ranking,
    Id,
    Username,
    Score, karma
  FROM Players 
) AS players_ranked_by_score
where Id = id_of_user 

这里的id_of_user是一个参数,里面包含了当前玩家的ID。要获取邻近的玩家当前用户:

(SELECT * FROM (
  SELECT
    RANK() OVER (ORDER BY Score desc ,Karma desc) AS ranking,
    Id,
    Username,
    Score, karma
  FROM Players 
) AS all_players_ranked
where ranking >= player_ranking - 2 and ranking <= player_ranking + 2;

这里的player_ranking是从上面的查询中得到的排名。

希望这对你有帮助!

更新:MySQL没有rank()这个函数(MS SQL、Oracle和Postgres都有)。我查了一下,找到了一个链接,里面解释了如何在MySQL中进行排名:http://www.artfulsoftware.com/infotree/queries.php?&bw=1024#460

撰写回答