Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:如何获得一系列活动的排行榜位置_Mysql_Sql - Fatal编程技术网

MySQL:如何获得一系列活动的排行榜位置

MySQL:如何获得一系列活动的排行榜位置,mysql,sql,Mysql,Sql,我有以下数据结构(简化): 我想知道(最好是最有效的方法): 如何获得用户在“联盟”中相对于其他用户的位置。以及——如果可能,使用一个查询(或子查询),如何按事件(例如,用户在第一个事件、第二个事件、第三个事件后的位置等)进行细分 我可以通过以下方式获得排行榜: select users.name, SUM(results.points) as points from results inner join users on results.user_id = users.id group b

我有以下数据结构(简化):

我想知道(最好是最有效的方法):

  • 如何获得用户在“联盟”中相对于其他用户的位置。以及——如果可能,使用一个查询(或子查询),如何按事件(例如,用户在第一个事件、第二个事件、第三个事件后的位置等)进行细分
我可以通过以下方式获得排行榜:

select users.name, SUM(results.points) as points
from results
inner join users on results.user_id = users.id
group by users.id
order by points DESC
但是,如果可能的话,我想知道用户的位置,而不必返回整个表

编辑:我提供了一些示例数据

理想输出:

| User ID | Rank  |
| 3       | 1     |
| 1       | 2     |
| 2       | 3     |
类似于(与此不完全相同,它是灵活的,只是显示用户在每个事件中的排名)

MySQL 8.0+支持此功能,因此使用
dense\u rank()
非常方便


8.0解决方案下的MySQL

由于您的版本是5.7,您可以模仿如下:

select 
  t.id,
  CASE WHEN @prevRank = points THEN @currRank
       WHEN @prevRank := points THEN @currRank := @currRank + 1
   END AS rank
from (
  select users.id, SUM(results.points) as points
  from results
  inner join users on results.user_id = users.id
  group by users.id
  order by points DESC
  ) t
  cross join (SELECT @currRank := 0, @prevRank := NULL) r
如果您需要特定
用户的数据
,请添加
WHERE
条件以过滤掉外部查询中的所有其他人:

select *
from (
<< above query here >>
) t
where id = ? -- your id here

您是否正在尝试创建一个用户输入用户名和事件名称,并希望在该事件后返回用户位置的内容?另外,如果您可以添加一些示例数据,这将非常有帮助。示例数据和输出将非常有用。您使用的是哪个版本的MySQL?我已经将示例数据添加到了gist链接中。我可以控制服务器,所以我可以使用任何版本的MySQL,但目前它是5.7。我试图创建一些东西,当用户登录时,它会显示他们当前的联盟位置,理想情况下,每个用户的位置图,在每个事件之后,可以看到位置随时间的变化,当用户登录pass userid并添加where条件,然后获得联盟位置抱歉,我知道怎么做,我已经用所需输出的示例更新了我的问题。@SteveEdson我已经编辑了我的答案,你能现在检查一下吗?这对所有用户都很有效,但是在其中添加一个
会将排名更改为1,因为没有其他人可以增加更新的答案来澄清我的意思。您还需要一个级别的select语句。太好了,谢谢。不要假设有一种方法可以显示每个事件后的排名(考虑到上一个事件的分数)?是的,这是可能的,但更复杂(特别是对于8.0以下的MySQL版本,因为您需要累积积分)。没问题,可以为MySQL 8提供一个示例吗?
SET @rowno = 0;
select UserID, max(points), @rowno:=@rowno+1 as rank  from 
(
select users.id as UserID ,users.name as users_name,events.name, SUM(results.points) as points
from results
inner join users on results.user_id = users.id
inner join events on results.event_id= events.id
group by users.id,events.name,users.name
order by points DESC
) as T
group by UserID

order by max(points) desc
select 
  t.id,
  CASE WHEN @prevRank = points THEN @currRank
       WHEN @prevRank := points THEN @currRank := @currRank + 1
   END AS rank
from (
  select users.id, SUM(results.points) as points
  from results
  inner join users on results.user_id = users.id
  group by users.id
  order by points DESC
  ) t
  cross join (SELECT @currRank := 0, @prevRank := NULL) r
select *
from (
<< above query here >>
) t
where id = ? -- your id here
select id, dense_rank() over (order by points desc) as `rank`
from (
  select users.id, SUM(results.points) as points
  from results
  inner join users on results.user_id = users.id
  group by users.id
  ) t
order by `rank`