it-swarm.asia

الحصول على رتبة مستخدم في جدول النتيجة

لدي جدول MySQL بسيط للغاية حيث أحفظ النتائج العالية. انها تشبهه:

Id     Name     Score

حتى الان جيدة جدا. السؤال هو: كيف أحصل على رتبة المستخدمين؟ على سبيل المثال ، لدي مستخدم Name أو Id وأريد الحصول على رتبته ، حيث يتم ترتيب جميع الصفوف بالترتيب التنازلي لـ Score.

مثال

Id  Name    Score
1   Ida     100
2   Boo     58
3   Lala    88
4   Bash    102
5   Assem   99

في هذه الحالة بالذات ، سيكون ترتيب Assem 3 ، لأنه حصل على ثالث أعلى درجة.

يجب أن يُرجع الاستعلام صفًا واحدًا ، يحتوي على (فقط) الترتيب المطلوب.

32
Michael
SELECT id, name, score, FIND_IN_SET( score, (
SELECT GROUP_CONCAT( score
ORDER BY score DESC ) 
FROM scores )
) AS rank
FROM scores

يعطي هذه القائمة:

id name  score rank
1  Ida   100   2
2  Boo    58   5
3  Lala   88   4
4  Bash  102   1
5  Assem  99   3

الحصول على درجة شخص واحد:

SELECT id, name, score, FIND_IN_SET( score, (    
SELECT GROUP_CONCAT( score
ORDER BY score DESC ) 
FROM scores )
) AS rank
FROM scores
WHERE name =  'Assem'

يعطي هذه النتيجة:

id name score rank
5 Assem 99 3

سيكون لديك مسح واحد للحصول على قائمة النقاط ، ومسح آخر أو تسعى للقيام بشيء مفيد معها. سيساعد فهرس العمود score على الأداء على الجداول الكبيرة.

35
cairnz

عندما يكون لدى العديد من الإدخالات نفس النتيجة ، يجب ألا يكون الترتيب التالي متتاليًا. يجب زيادة الترتيب التالي بعدد الدرجات التي تشترك في نفس الترتيب.

لعرض درجات مثل هذه يتطلب متغيرين رتبة

  • متغير رتبة لعرضه
  • متغير رتبة لحساب

فيما يلي نسخة أكثر استقرارًا من التصنيف مع العلاقات:

SET @rnk=0; SET @rank=0; SET @curscore=0;
SELECT score,ID,rank FROM
(
    SELECT AA.*,BB.ID,
    (@rnk:[email protected]+1) rnk,
    (@rank:=IF(@curscore=score,@rank,@rnk)) rank,
    (@curscore:=score) newscore
    FROM
    (
        SELECT * FROM
        (SELECT COUNT(1) scorecount,score
        FROM scores GROUP BY score
    ) AAA
    ORDER BY score DESC
) AA LEFT JOIN scores BB USING (score)) A;

دعونا نجرب هذا مع عينة من البيانات. أولا هنا عينة البيانات:

use test
DROP TABLE IF EXISTS scores;
CREATE TABLE scores
(
    id int not null auto_increment,
    score int not null,
    primary key (id),
    key score (score)
);
INSERT INTO scores (score) VALUES
(50),(40),(75),(80),(55),
(40),(30),(80),(70),(45),
(40),(30),(65),(70),(45),
(55),(45),(83),(85),(60);

دعونا تحميل بيانات العينة

mysql> DROP TABLE IF EXISTS scores;
Query OK, 0 rows affected (0.15 sec)

mysql> CREATE TABLE scores
    -> (
    ->     id int not null auto_increment,
    ->     score int not null,
    ->     primary key (id),
    ->     key score (score)
    -> );
Query OK, 0 rows affected (0.16 sec)

mysql> INSERT INTO scores (score) VALUES
    -> (50),(40),(75),(80),(55),
    -> (40),(30),(80),(70),(45),
    -> (40),(30),(65),(70),(45),
    -> (55),(45),(83),(85),(60);
Query OK, 20 rows affected (0.04 sec)
Records: 20  Duplicates: 0  Warnings: 0

بعد ذلك ، دعنا نهيئ متغيرات المستخدم:

mysql> SET @rnk=0; SET @rank=0; SET @curscore=0;
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

الآن ، هنا ناتج الاستعلام:

mysql> SELECT score,ID,rank FROM
    -> (
    ->     SELECT AA.*,BB.ID,
    ->     (@rnk:[email protected]+1) rnk,
    ->     (@rank:=IF(@curscore=score,@rank,@rnk)) rank,
    ->     (@curscore:=score) newscore
    ->     FROM
    ->     (
    ->         SELECT * FROM
    ->         (SELECT COUNT(1) scorecount,score
    ->         FROM scores GROUP BY score
    ->     ) AAA
    ->     ORDER BY score DESC
    -> ) AA LEFT JOIN scores BB USING (score)) A;
+-------+------+------+
| score | ID   | rank |
+-------+------+------+
|    85 |   19 |    1 |
|    83 |   18 |    2 |
|    80 |    4 |    3 |
|    80 |    8 |    3 |
|    75 |    3 |    5 |
|    70 |    9 |    6 |
|    70 |   14 |    6 |
|    65 |   13 |    8 |
|    60 |   20 |    9 |
|    55 |    5 |   10 |
|    55 |   16 |   10 |
|    50 |    1 |   12 |
|    45 |   10 |   13 |
|    45 |   15 |   13 |
|    45 |   17 |   13 |
|    40 |    2 |   16 |
|    40 |    6 |   16 |
|    40 |   11 |   16 |
|    30 |    7 |   19 |
|    30 |   12 |   19 |
+-------+------+------+
20 rows in set (0.18 sec)

يرجى ملاحظة أن العديد من المعرّفات التي تشترك في نفس النتيجة لها نفس الترتيب. لاحظ أيضًا أن الرتبة ليست متتالية.

جربها !!!

31
RolandoMySQLDBA
SELECT 
    id, 
    Name,
    1+(SELECT count(*) from table_name a WHERE a.Score > b.Score) as RNK,
    Score
FROM table_name b;
14
a1ex07

أحد الخيارات هو استخدام متغيرات USER:

SET @i=0;
SELECT id, name, score, @i:[email protected]+1 AS rank 
 FROM ranking 
 ORDER BY score DESC;
9
Derek Downey

الإجابة المقبولة لديها مشكلة محتملة. إذا كانت هناك درجتان متطابقتان أو أكثر ، فستكون هناك فجوات في الترتيب. في هذا المثال المعدل:

 id name  score rank
 1  Ida   100   2
 2  Boo    58   5
 3  Lala   99   3
 4  Bash  102   1
 5  Assem  99   3

الدرجة 58 لها المرتبة 5 ، ولا يوجد رتبة 4.

إذا كنت تريد التأكد من عدم وجود ثغرات في التصنيف ، استخدم DISTINCT في GROUP_CONCAT لإنشاء قائمة بالدرجات المميزة:

SELECT id, name, score, FIND_IN_SET( score, (
SELECT GROUP_CONCAT( DISTINCT score
ORDER BY score DESC ) FROM scores)
) AS rank
FROM scores

نتيجة:

id name  score rank
1  Ida   100   2
2  Boo    58   4
3  Lala   99   3   
4  Bash  102   1
5  Assem  99   3

هذا يعمل أيضًا للحصول على رتبة مستخدم واحد:

SELECT id, name, score, FIND_IN_SET( score, (    
SELECT GROUP_CONCAT(DISTINCT score
ORDER BY score DESC ) 
FROM scores )
) AS rank
FROM scores
WHERE name =  'Boo'

نتيجة:

id name score rank
 2  Boo   58    4
4
Mahesh Lakher

إليك أفضل إجابة:

SELECT 1 + (SELECT count( * ) FROM highscores a WHERE a.score > b.score ) AS rank FROM
highscores b WHERE Name = 'Assem' ORDER BY rank LIMIT 1 ;

سيعيد هذا الاستعلام:

3

3
FamerJoe

هذا الحل يعطي DENSE_RANK في حالة العلاقات:

SELECT *,
IF (@score=s.Score, @rank:[email protected], @rank:[email protected]+1) rank,
@score:=s.Score score
FROM scores s,
(SELECT @score:=0, @rank:=0) r
ORDER BY points DESC
3
Arvind07

أليس العمل التالي (على افتراض أن الجدول الخاص بك يسمى عشرات)؟

SELECT COUNT(id) AS rank FROM Scores 
WHERE score <= (SELECT score FROM Scores WHERE Name = "Assem")
0
bfredo123