الترتيب داخل Django orm أو SQL؟
-
22-09-2019 - |
سؤال
لدي قائمة ضخمة تصنفها القيم المختلفة (على سبيل المثال الدرجات)
لذلك أمسك القائمة التي طلبتها هذه القيم:
players = Player.objects.order_by('-score', '-karma')
وأود أن:
- احصل على لاعب واحصل على اللاعبون المجاورون
P1 النتيجة: 123
P2 النتيجة: 122
أنت! نتيجة:110
P3 النتيجة: 90
P2 النتيجة: 89
- والاستيلاء على موقع!
أنت في المرتبة رقم 1234 للحصول على درجة
أنت في المرتبة رقم 9876 لكارما
ان مساعدة سيكون محل تقدير كبير جدا. شكرًا :)
المحلول
للحصول على تصنيف المستخدم:
(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 هي المعلمة التي تحتوي على معرف اللاعب الحالي. للحصول على اللاعبين المجاورة و المستخدم الحالي:
(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;
حيث هو لاعب هو الترتيب الذي تم الحصول عليه من الاستعلام أعلاه.
أتمنى أن يساعد!
تحديث: MySQL ليس لديه وظيفة Rank () (MS SQL ، Oracle ، Postgres لها واحدة). نظرت حولي وحصلت على هذا الرابط يشرح كيفية القيام بالترتيب في MySQL: http://www.artfulsoftware.com/infotree/queries.php؟&bw=1024#460.
نصائح أخرى
هذه الأنواع من الأشياء يصعب القيام بها دائمًا. ستحتاج إلى استفسارات متعددة لكل واحد.
لذلك ، للحصول على اللاعبين قبل وبعد وضعك عند طلبه من النتيجة ، ستحتاج أولاً إلى معرفة ماهية هذا الموقف. (لاحظ أن هذا يفترض أنه لا يمكن أن يكون لديك أكثر من شخص يحمل نفس النتيجة ، والتي قد لا تكون بالضرورة صحيحة.)
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]
لقد فعلت ذلك مع 3 استفسارات مع 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])