Pergunta

Eu tenho uma lista enorme classificada por vários valores (por exemplo, pontuações)

Então eu pego a lista encomendada por esses valores:

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

Eu gostaria de:

  • Pegue um jogador e pegue o jogadores vizinhos

Pontuação P1: 123

Pontuação p2: 122

VOCÊS! pontuação:110

P3 Pontuação: 90

Pontuação p2: 89

  • Pegue o posição!

Você está classificado como #1234 para pontuação

Você está classificado como #9876 para o karma


A ajuda seria muito apreciada. obrigado :)

Foi útil?

Solução

Para obter a classificação do usuário:

(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 

Onde id_of_user é o parâmetro que contém o ID do jogador atual. Para conseguir os jogadores vizinhos e o usuário atual:

(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;

Onde Player_ranking é o ranking obtido da consulta acima.

Espero que ajude!

Atualizar: MySQL não possui uma função de classificação () (MS SQL, Oracle, Postgres tem uma). Olhei em volta e recebi esse link explicando como fazer a classificação no MySQL: http://www.artfulsoftware.com/infotree/queries.php?&bw=1024#460.

Outras dicas

Esse tipo de coisa é sempre muito difícil de fazer. Você precisará de várias consultas para cada uma.

Então, para obter os jogadores antes e depois da sua posição, quando encomendados por pontuação, primeiro você precisará descobrir qual é essa posição. (Observe que isso pressupõe que você não pode ter mais de uma pessoa com a mesma pontuação, o que pode não ser necessariamente verdadeiro.)

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]

Fiz isso com 3 consultas com o ORM, mas acho que menos contagem de consultas seria melhor:

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])
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top