我正在尝试找到一种方法,可以通过多个类别对人们的分数进行排名。 该表包含每个玩家的列表以及他们参加的事件和得分。
查询需要根据每个事件中的得分为每个玩家分配等级。 (在事件1和事件2中分配的等级应该完全分开。)
如果某个事件中缺少玩家,则应为他们分配(该类别中的玩家总数+ 1)的排名
我可以对1个类别进行基本排名。很简单但是我什至不知道该怎么做。
表中的数据
+--------+-------+---------+
| Name | Score | Event # |
+--------+-------+---------+
| Kevin | 73 | Event 1 |
| George | 69 | Event 1 |
| Henry | 70 | Event 1 |
| | | |
| George | 45 | Event 2 |
| Kevin | 65 | Event 2 |
| Henry | 65 | Event 2 |
| Daniel | 50 | Event 2 |
+--------+-------+---------+
预期回报
+---------+--------+------+
| Event # | Name | Rank |
+---------+--------+------+
| Event 1 | Kevin | 1 |
| Event 1 | Henry | 2 |
| Event 1 | George | 3 |
| Event 1 | Daniel | 4 |
| Event 2 | Kevin | 1 |
| Event 2 | Henry | 1 |
| Event 2 | Daniel | 3 |
| Event 2 | George | 4 |
+---------+--------+------+
请注意,排名并不密集! 我使用的是MySql 5.7。
实际上,我有50多个活动和数百人。
这是我排名1项赛事的条件
SELECT
IF( SCORE =@_last_rank,@curRank:=@curRank,@curRank:=@_sequence) AS RANK,
NAME,
EVENT,
@_sequence:=@_sequence+1,@_last_rank:= SCORE
FROM (SELECT * FROM database WHERE EVENT = $event) p,
(SELECT @curRank := 1, @_sequence:=1, @_last_rank:=0) r
ORDER BY RANK, NAME
答案 0 :(得分:0)
此sql语句
Select eventno,Name,rank
From
(Select eventno,Name,
CASE
WHEN @event = eventno THEN @rownum := @rownum + 1
ELSE
@rownum := 1
END as rank,
@event := eventno
From table1 t
JOIN (SELECT @rownum := 0) r
JOIN (SELECT @event := (Select Eventno from table1 Limit 1)) s
ORDER BY t.eventno,t.score) x;
CREATE TABLE table1
(`Name` varchar(6), `Score` int, `Eventno` varchar(7))
INSERT INTO table1
(`Name`, `Score`, `Eventno`)
VALUES
('Kevin', 73, 'Event 1'),
('George', 69, 'Event 1'),
('Henry', 70, 'Event 1'),
('George', 45, 'Event 2'),
('Kevin', 65, 'Event 2'),
('Henry', 65, 'Event 2'),
('Daniel', 50, 'Event 2')
给出以下结果:
eventno Name rank
Event 1 George 1
Event 1 Henry 2
Event 1 Kevin 3
Event 2 George 1
Event 2 Daniel 2
Event 2 Kevin 3
Event 2 Henry 4
7 rows
答案 1 :(得分:0)
以下方法避免了(不可靠的)使用用户变量和高度复杂的查询。它使用临时表并利用MyISAM的每组自动输入功能,以每组生成行号。为了从行号中获得排名,使用了带有MIN(row_number)
的GROUP BY查询。
drop temporary table if exists tmp_scores;
create temporary table tmp_scores(
rn int auto_increment,
event varchar(50),
name varchar(50),
score int,
primary key (event, rn)
)engine=myisam;
insert into tmp_scores(event, name, score)
select e.event, n.name, t.score
from (select distinct t.event from mytable t) e
cross join (select distinct t.name from mytable t) n
left join mytable t on t.event = e.event and t.name = n.name
order by e.event, t.score is null, t.score desc;
drop temporary table if exists tmp_rank_by_score;
create temporary table tmp_rank_by_score(
event varchar(50),
score int,
rank int,
primary key (event, rank)
)engine=myisam;
insert into tmp_rank_by_score(event, score, rank)
select event, score, min(rn) as rank
from tmp_scores
group by event, score;
select s.event, s.name, s.score, r.rank
from tmp_scores s
join tmp_rank_by_score r on r.event = s.event and r.score <=> s.score
order by r.event, r.rank;
drop temporary table if exists tmp_rank_by_score;
drop temporary table if exists tmp_scores;
结果:
| event | name | score | rank |
| ------- | ------ | ----- | ---- |
| Event 1 | Kevin | 73 | 1 |
| Event 1 | Henry | 70 | 2 |
| Event 1 | George | 69 | 3 |
| Event 1 | Daniel | | 4 |
| Event 2 | Kevin | 65 | 1 |
| Event 2 | Henry | 65 | 1 |
| Event 2 | Daniel | 50 | 3 |
| Event 2 | George | 45 | 4 |