我有一个名为 'winners' 的表格,其中包含 'id'、'category'、'score'、'rank' 列。
我需要更新我的表并在子类别 (category_id) 中指定一个排名,根据样本,该排名为 2,但将来可能会更多。
我发现的大多数答案都是基于 select 语句,这些语句只是倾向于输出表格视图,但我确实找到了一个非常好的“更新”答案(https://stackoverflow.com/a/2727239/4560380)特别是答案更新领带必须共享相同的排名。
样本
CREATE TABLE winners (
id int,
category_id int,
score double,
rank int
);
INSERT INTO winners VALUES
(1, 1, 4.36, NULL),
(2, 1, 2.35, NULL),
(3, 1, 1.25, NULL),
(4, 2, 4.21, NULL),
(5, 2, 3.33, NULL),
(6, 1, 4.24, NULL),
(7, 1, 1.22, NULL),
(8, 1, 1.25, NULL),
(9, 2, 4.21, NULL),
(10, 2, 3.63, NULL);
+----------+-------------+-------+------+
| id | category_id | score | rank |
+----------+-------------+-------+------+
| 1 | 1 | 4.36 | |
| 2 | 1 | 2.35 | |
| 3 | 1 | 1.25 | |
| 4 | 2 | 4.21 | |
| 5 | 2 | 3.33 | |
| 6 | 1 | 4.24 | |
| 7 | 1 | 1.22 | |
| 8 | 1 | 1.25 | |
| 9 | 2 | 4.21 | |
| 10 | 2 | 3.63 | |
+----------+-------------+-------+------+
当只有一个类别需要担心时,上面的链接答案非常适用于数据,但当有多个类别或子组要在其中进行排名时则不行。
我曾尝试在代码中添加 where 子句(第 8 行)
1. UPDATE winners
2. JOIN (SELECT w.score,
3. IF(@lastPoint <> w.score,
4. @curRank := @curRank + 1,
5. @curRank) AS rank,
6. @lastPoint := w.rating
7. FROM winners w
8. WHERE category_id = 1
9. JOIN (SELECT @curRank := 0, @lastPoint := 0) r
10. ORDER BY w.score DESC
11. ) ranks ON (ranks.score = winners.score)
12. SET winners.rank = ranks.rank;
试图为每个 category_id 运行代码两次,但脚本失败。
为多个类别修改上述答案的任何选项都很棒。
需要的结果只是为了澄清(在类别中排名)。
+----------+-------------+-------+------+
| id | category_id | score | rank |
+----------+-------------+-------+------+
| 1 | 1 | 4.36 | 1 |
| 6 | 1 | 4.24 | 2 |
| 2 | 1 | 2.35 | 3 |
| 8 | 1 | 1.25 | 4 |
| 3 | 1 | 1.25 | 4 |
| 7 | 1 | 1.22 | 5 |
| 4 | 2 | 4.21 | 1 |
| 9 | 2 | 4.21 | 1 |
| 10 | 2 | 3.63 | 2 |
| 5 | 2 | 3.33 | 3 |
+----------+-------------+-------+------+
多谢你们!
更新
设法找到另一段代码https://stackoverflow.com/a/13270603/4560380,我最初以某种方式错过了它,并且能够成功地使用每个 category_id 的 where 子句对其进行修改。这不是一种理想的方式 - 为多个类别运行多次,但此时它很好。
set @currentRank = 0,
@lastRating = null,
@rowNumber = 1;
update winners r
inner join (
select
score,
@currentRank := if(@lastRating = score, @currentRank, @rowNumber) rank,
@rowNumber := @rowNumber + if(@lastRating = score, 0, 1) rowNumber,
@lastRating := score
from winners
where category_id = 1
order by score desc
) var on var.score = r.score
set r.rank = var.rank
在 1 个脚本运行中对排名中的多个类别进行更“自动”处理的进一步答案仍然非常受欢迎和赞赏。
谢谢
更新
只是注意到我找到的答案不能很好地处理零分数(0.00),并将它们排在其他分数的中间。
下面的 shawnt00 答案正在工作并正确评估零分数。 https://stackoverflow.com/a/34667112/4560380