在MySQL中排名

时间:2015-10-05 08:46:05

标签: php mysql

目前我正在开发一个支持比赛的系统。在本次比赛中,有11名评委给参赛者评分。该等级存储在每个法官的表格中。使用以下Select语句,我从MySQL database(以及其他表中的inner joinsselect其他信息中检索总分。)

现在我想在这个系统中进行排名,其中也考虑了其他情况。我在这个论坛上尝试了几个mysql解决方案。但不知何故,声明总是不正确的。希望有人可以帮助我。

SELECT optreden.id, optreden.wedstrijd, optreden.jaartal, 
liedje.titel, club.volledige_clubnaam,
(SELECT SUM(score.score_lied) FROM score WHERE score.optreden=optreden.id) AS score
FROM optreden
INNER JOIN liedje ON optreden.liedje=liedje.id
INNER JOIN club ON liedje.uitvoerende_club=club.id
WHERE optreden.wedstrijd="voorselectie" AND optreden.jaartal=2014
GROUP BY optreden.id
ORDER BY score_lied DESC

通过此查询,我得到以下结果:

+----+--------------+------+----------+--------------+------+
| id | Competition  | Year | Title    | Artist (club)| Score|
+----+--------------+------+----------+--------------+------+
| 12 | voorselectie | 2014 | Song 1   | Club 1       | 792  |
| 16 | voorselectie | 2014 | Song 2   | Club 2       | 600  |
| 10 | voorselectie | 2014 | Song 3   | Club 3       | 600  |
| 11 | voorselectie | 2014 | Song 3   | Club 3       | 500  |
| 12 | voorselectie | 2014 | Song 3   | Club 3       | 400  |

查询从以下表中获取信息:

  • 得分:在此表中,11名评委给出的分数存储为 行项目(结果如下);
  • Optreden:在此表中,俱乐部和歌曲的信息是相互关联的;
  • 俱乐部:俱乐部提供的信息, 如姓名;
  • Liedje:关于这首歌的信息 俱乐部。 所有表都由id链接。在结果中,应该有一个专栏,以及俱乐部的排名。

表格得分的结果如下:

+----+----+--------+----+
| ID | Pid| Userid | 85 |
+----+----+--------+----+
| 1  | 12 | 444    | 85 |
| 12 | 12 | 454    | 92 |
| 13 | 12 | 445    | 87 |
| 14 | 12 | 446    | 56 |
| 15 | 12 | 447    | 81 |
| 16 | 12 | 448    | 78 |
| 17 | 12 | 449    | 55 |
| 18 | 12 | 450    | 69 |
| 19 | 12 | 451    | 88 |
| 20 | 12 | 452    | 69 |
| 21 | 12 | 453    | 32 |
+----+----+--------+----+

列表示以下内容: - ID:表格中得分的id; - Pid:表演的id(这个表演俱乐部和歌曲是相互关联的); - 用户名:1​​1名法官的userid; - 得分:每位法官给出的score

最终结果应如下:

+----+--------------+------+----------+--------------+------+------+
| id | Competition  | Year | Title    | Artist (club)| Score| Rank |
+----+--------------+------+----------+--------------+------+------+
| 12 | voorselectie | 2014 | Song 1   | Club 1       | 792  | 1    |
| 16 | voorselectie | 2014 | Song 2   | Club 2       | 600  | 2    |
| 10 | voorselectie | 2014 | Song 3   | Club 3       | 600  | 2    |
| 11 | voorselectie | 2014 | Song 3   | Club 3       | 500  | 4    |
| 12 | voorselectie | 2014 | Song 3   | Club 3       | 400  | 5    |

我之前和现在再次尝试过Neville的解决方案。我重写了SQL statement如下:

SELECT optreden.id, optreden.wedstrijd, optreden.jaartal, 
liedje.titel, club.volledige_clubnaam,
(SELECT SUM(score.score_lied) FROM score WHERE score.optreden=optreden.id) AS score, CASE
WHEN @prev_value = score THEN @rank_count
WHEN @prev_value := score THEN @rank_count := @rank_count + 1
END AS rank,
FROM optreden
INNER JOIN liedje ON optreden.liedje=liedje.id
INNER JOIN club ON liedje.uitvoerende_club=club.id
WHERE optreden.wedstrijd="voorselectie" AND optreden.jaartal=2014
GROUP BY optreden.id
ORDER BY score_lied DESC

我收到错误:Unknown column 'score' in 'field list'.

2 个答案:

答案 0 :(得分:0)

您似乎只是因为没有字段得分而得到此错误...我已将您的内部SELECT提取到JOIN中,因此可以直接使用真实字段。 (虽然没有测试,抱歉)

SELECT optreden.id, optreden.wedstrijd, optreden.jaartal, 
liedje.titel, club.volledige_clubnaam,
SUM(score.score_lied) AS score, CASE
WHEN @prev_value = SUM(score.score_lied) THEN @rank_count
WHEN @prev_value := SUM(score.score_lied) THEN @rank_count := @rank_count + 1
END AS rank,
FROM optreden
INNER JOIN liedje ON optreden.liedje=liedje.id
INNER JOIN club ON liedje.uitvoerende_club=club.id
LEFT JOIN score ON score.optreden=optreden.id
WHERE optreden.wedstrijd="voorselectie" AND optreden.jaartal=2014
GROUP BY optreden.id
ORDER BY score_lied DESC

请注意,这种排名可能会面临另一个小问题:通常情况下,当两个实体最终排在同一排名时,下一个排名不会给下一个人。这是我的一个例子,两个人排在3:

1, 2, 3, 3, 5

但是在你的代码中,它会给出:

1, 2, 3, 3, 4

我希望这会有所帮助。

答案 1 :(得分:0)

我尝试过几件事。但是,我忘了告诉你一个我将使用的重要功能。俱乐部的排名应该通过大屏幕上的演示来呈现。因此,MySQL代码发生了一些变化。

我在数据库中添加了支持表。在此支持表中,使用INSERT INTO ... SELECT语句记录分数总和。

完成此插入后。启动更新脚本,在表格中进行排名,并进行正确的计算。

这是更新声明:

SET @rank=0, @last_score = null, @tie_build_up = 0;
UPDATE ranking_voorselectie_lied
SET rank= @rank:= if(@last_score = totaal_score_lied, @rank, @rank+@tie_build_up+1),
tie_build_up= @tie_build_up:= if(@last_score = totaal_score_lied, @tie_build_up+1, 0),
last_score= @last_score:= totaal_score_lied
WHERE wedstrijd="voorselectie" AND jaar=2014
ORDER BY totaal_score_lied DESC;

这给了我以下结果:

        +--------------+------+----------+-------------------+------+-----+------------+
|  Wedstrijd   | Jaar | Optreden | totaal_score_lied | Rank | Tie | last_score |
+--------------+------+----------+-------------------+------+-----+------------+
| voorselectie | 2014 |       12 |               792 |    1 |   0 |        792 |
| voorselectie | 2014 |       16 |                82 |    2 |   0 |         82 |
| voorselectie | 2014 |       10 |                73 |    3 |   0 |         73 |
| voorselectie | 2014 |       15 |                51 |    4 |   0 |         51 |
| voorselectie | 2014 |        3 |                50 |    5 |   0 |         50 |
| voorselectie | 2014 |       11 |                42 |    6 |   0 |         42 |
| voorselectie | 2014 |       13 |                38 |    7 |   0 |         38 |
| voorselectie | 2014 |        8 |                38 |    7 |   1 |         38 |
| voorselectie | 2014 |       14 |                37 |    9 |   0 |         37 |
| voorselectie | 2014 |        5 |                35 |   10 |   0 |         35 |
| voorselectie | 2014 |        4 |                33 |   11 |   0 |         33 |
| voorselectie | 2014 |        7 |                25 |   12 |   0 |         25 |
| voorselectie | 2014 |        9 |                23 |   13 |   0 |         23 |
+--------------+------+----------+-------------------+------+-----+------------+