【问题标题】:MySQL Winning Streak for every Player每位玩家的 MySQL 连胜记录
【发布时间】:2015-08-26 15:43:19
【问题描述】:

我有一个表格,其中包含游戏的赢家和输家统计数据:

id           winner_id   loser_id 

1            1          2             
2            1          2             
3            3          4             
4            4          3             
5            1          2             
6            2          1             
7            3          4             
8            3          2   
9            3          5             
10           3          6             
11           2          3   
12           3          6             
13           2          3         

我想要一个结果表,我可以在其中找到游戏中每个玩家的最高连胜纪录。当一名球员输掉一场比赛(player_id = loster_id)时,他的连胜记录被打破。它应该看起来像:

player_id    win_streak

1            3                     
2            2                     
3            4                       
4            1                      
5            0                      
6            0                      

我尝试了许多使用用户定义变量等的查询,但我找不到解决方案。谢谢!

SQL 小提琴:http://sqlfiddle.com/#!9/3da5f/1

【问题讨论】:

  • 感谢您的链接!我想知道为什么它出现在我的问题中;)
  • 你的表应该反映什么?最好的连胜纪录还是最近的连胜纪录?
  • 那么你想要的结果对于你的例子是错误的......你应该为每个玩家添加其余的条纹......
  • @Jorge Campos,你是对的!我的目标是每个球员的最高连胜纪录。我编辑了问题。
  • 好吧,要么你将不得不使用我在 mysql 游标内或在你的应用程序代码中谈到的那个变量。您必须根据扫描期间稍后可能发生或不发生的事件进行顺序聚合(计数)(可能稍后出现的结果记录可能会结束连续或增加计数器)。你的 SQL 代码真的很难看。最好保持您的数据模型干净,并依靠您的应用代码来做到这一点。

标签: mysql sql


【解决方案1】:

这和亚历克斯的做法一样吗?我不太确定,只是它似乎有一个明显的优势.... ;-)

SELECT player_id, MAX(CASE WHEN result = 'winner' THEN running ELSE 0 END) streak 
  FROM 
     ( SELECT *
            , IF(player_id = @prev_player,IF(result=@prev_result,@i:=@i+1,@i:=1),@i:=1) running
            , @prev_result := result 
            , @prev_player:=player_id
         FROM 
            ( SELECT id, 'winner' result, winner_id player_id FROM my_table
               UNION
              SELECT id, 'loser', loser_id FROM my_table
            ) x
            , 
            ( SELECT @i:=1,@prev_result = '',@prev_player:='' ) vars
        ORDER  
           BY x.player_id
            , x.id
     ) a
 GROUP 
    BY player_id;

【讨论】:

  • 玩家 5 和 6!好一个!但仍然没有按照 OP 的要求(在 cmets 中)显示所有玩家的所有条纹。 +1 虽然
  • @JorgeCampos 你失去了我
  • @JorgeCampos 我检查了草莓的查询 - 它适用于我的小提琴。你的观点是什么?
  • OP 在 cmets 上说他需要所有球员的所有连胜,然后他的查询给你:1-3; 2-2; 3-4; 4-1; 5-0; 6-0 什么时候应该显示:1-3; 2-1; 2-2; 3-1; 3-4; 3-1; 4-1; 5-0; 6-0。在 cmets 中引用 OP:I would like to have the overall winning streak for each player@LukeP 询问后
  • 你能在 sqlfiddle 中证明这一点
【解决方案2】:

我想您最好在 php(或您使用的任何其他语言)方面这样做。

但只是为了给您一些想法,并作为一些独特案例的实验和示例(希望它可以在某些地方有用)

这是我的方法:

http://sqlfiddle.com/#!9/57cc65/1

SELECT r.winner_id,
  (SELECT MAX(IF(winner_id=r.winner_id,IF(@i IS NULL, @i:=1,@i:=@i+1), IF(loser_id = r.winner_id, @i:=0,0)))
   FROM Results r1
   WHERE r1.winner_id = r.winner_id
     OR r1.loser_id = r.winner_id
  GROUP BY IF(winner_id=r.winner_id, winner_id,loser_id)) win_streak

FROM ( SELECT winner_id
      FROM Results
      GROUP BY winner_id
      ) r

它现在不是返回所有的 id,而是只返回曾经赢过的人。所以为了让它更好,可能你有user 表。如果是这样,它将简化查询。如果你没有user 表,你需要union all 不知何故从未赢过的用户。

如果有任何问题欢迎您。

【讨论】:

  • Alex,感谢您的快速响应!是的,我有您在回答中提到的这个用户表。我的另一个目标是更新这个 user 表,其中包含每个玩家的连胜记录。我在 result table 上尝试了您的查询,但每个玩家的结果 win_streak 为 1。我不理解这种行为,但我正在尝试为我的数据库修复它。目前我有约 2000 名独特的玩家和约 110.000 个结果(游戏统计数据)。如果我尝试使用您的连续查询更新我的 user 表,它将永远加载:/
  • 只需提供您的results 表数据集,您就可以选择 1、2、3 个玩家并创建小提琴。到时候我们就可以弄清楚了。因为如您所见,我的查询适用于您提供的示例。顺便说一句 - 这就是我从一开始就告诉你的:这种查询没有最好的性能。因此,您可以在循环中运行此查询,但有一些限制,例如:WHERE winner_id>10 AND winner_id<=20
  • 我不相信这个查询可以正常工作 - 但(我认为)只是因为@i 的启动方式存在问题。
  • @Strawberry 我也没有 :-) 但我需要作者提供一些东西来继续开发。这从一开始就是一个非常奇怪的问题。因此,如果最终没有人需要,我只是不想浪费额外的时间来订购和分组所有东西。
  • @Alex 我创建了一个小提琴,您的查询运行良好! link 我的数据库中的问题(大约 2000 个独立玩家和大约 110.000 个结果):每个 win_streak 都是 1...
猜你喜欢
  • 2022-01-26
  • 1970-01-01
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多