2173. 最多连胜的次数

SQL架构

表: Matches

+-------------+------+
| Column Name | Type |
+-------------+------+
| player_id   | int  |
| match_day   | date |
| result      | enum |
+-------------+------+
(player_id, match_day) 是该表的主键。
每一行包括了:参赛选手 id、 比赛时间、 比赛结果。
比赛结果(result)的枚举类型为 ('Win', 'Draw', 'Lose')。

选手的 连胜数 是指连续获胜的次数,且没有被平局或输球中断。

写一个SQL 语句来计算每个参赛选手最多的连胜数

结果可以以任何顺序返回。

结果格式如下例所示:

示例 1:

输入: 
Matches 表:
+-----------+------------+--------+
| player_id | match_day  | result |
+-----------+------------+--------+
| 1         | 2022-01-17 | Win    |
| 1         | 2022-01-18 | Win    |
| 1         | 2022-01-25 | Win    |
| 1         | 2022-01-31 | Draw   |
| 1         | 2022-02-08 | Win    |
| 2         | 2022-02-06 | Lose   |
| 2         | 2022-02-08 | Lose   |
| 3         | 2022-03-30 | Win    |
+-----------+------------+--------+
输出: 
+-----------+----------------+
| player_id | longest_streak |
+-----------+----------------+
| 1         | 3              |
| 2         | 0              |
| 3         | 1              |
+-----------+----------------+
解释: 
Player 1:
从 2022-01-17 到 2022-01-25, player 1连续赢了三场比赛。
2022-01-31, player 1 平局.
2022-02-08, player 1 赢了一场比赛。
最多连胜了三场比赛。

Player 2:
从 2022-02-06 到 2022-02-08, player 2 输了两场比赛。
最多连赢了0场比赛。

Player 3:
2022-03-30, player 3 赢了一场比赛。
最多连赢了一场比赛。

进阶: 如果我们想计算最长的连续不输的次数(即获胜或平局),你将如何调整?

# Write your MySQL query statement below
-- select
-- player_id,count(1) longest_streak
-- from
-- (
-- select
-- player_id,match_day ,subdate( match_day,interval  row_number() over(partition by player_id order by match_day) day ) sb
-- from
-- Matches
-- where result = 'Win'
-- ) s1
-- 
-- group by player_id, sb
with  t0  as (
   select
   distinct player_id
   from
   Matches
)
, t1 as (select #对player_id 分组 按 日期顺序标号 
player_id,match_day , row_number() over(partition by player_id order by match_day) ro,result
from
Matches
), t2 as (
select
player_id, ro - row_number() over(partition by player_id order by ro) sb
from
t1
where result = 'win'
)
,t3 as (
select
player_id,max(c) longest_streak 
from
(
select
player_id,count(1) c
from
t2
group by
player_id,sb
) s1
group by player_id)


select
t0.player_id,ifnull(longest_streak,0)  longest_streak
from
t0 left join t3
using(player_id)

先按照id分组,按照日期排序给出rk1,再按照日期和结果分组,按照日期给出rk2:

# Write your MySQL query statement below
#计算连续次数:
#1、先按照id分组,按照日期排序给出rk1,再按照日期和结果分组,按照日期给出rk2
#2、按照id和rk1-rk2进行分组,并且统计id连续结果为胜的次数
#3、再group by求最大的连胜次数

with temp as
(
    select
    player_id,sum(result='Win') s 
    from
    (
        select player_id,match_day,result,
        row_number() over (partition by player_id order by match_day) rk1,
        row_number() over (partition by player_id,result order by match_day) rk2
        from Matches
    )a
    group by player_id,rk1-rk2
)

select 
player_id,max(s) longest_streak
from temp 
group by player_id

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值