如何使用 MySQL 计算最长的不败记录?

Posted

技术标签:

【中文标题】如何使用 MySQL 计算最长的不败记录?【英文标题】:How to calculate longest undefeated streak using MySQL? 【发布时间】:2015-08-25 14:06:05 【问题描述】:

我正在创建一个网页,其中列出了单个团队的各种最长连胜纪录,但在尝试计算所涉及的结果类型组合的连胜纪录时遇到了问题。

数据以表格形式呈现如下...

日期结果 gf ga 类型 compfull -------------------------------------------------- 1980-08-16 W 3 0 联赛分区 1 1980-08-19 L 1 2 联赛分区 1 1980-08-23 W 3 1 联赛分区 1 1980-08-26 W 2 0 联赛分区 1 1980-08-30 D 2 2 联赛分区 1 等等...

使用以下查询(或类似查询),我可以确定最长的输赢甚至比赛得分。

SELECT result, type, MIN(date) as StartDate, MAX(date) as EndDate, COUNT(*) as Games 
FROM (SELECT result, type, date, compfull, (SELECT COUNT(*) 
FROM resultengine R 
WHERE R.result <> RE.result
AND R.date <= RE.date) as RunGroup
FROM resultengine RE) A WHERE result='W' GROUP BY result, RunGroup ORDER BY Games

这是基于我找到的优秀资源here。它完全按照我的意愿执行并告诉我我想知道的内容 - 如果我更改为

,这同样适用
result='L'

我想不通的是如何计算不败比赛的最长连胜纪录,即没有 L 的最长连胜纪录。反之亦然。

我试过以下查询无济于事:

SELECT result, type, MIN(date) as StartDate, MAX(date) as EndDate, COUNT(*) as Games 
FROM (SELECT result, type, date, compfull, (SELECT COUNT(*) 
FROM resultengine R 
WHERE R.result <> RE.result
AND R.date <= RE.date) as RunGroup
FROM resultengine RE) A WHERE result!='W' GROUP BY result, RunGroup ORDER BY Games

我也尝试将查询更改为:

WHERE result='W' OR result='D'

同样,这不起作用。两种尝试都反映了用于提供最长连续 Ws 或 Ls 的查询——我的数据的手动计数告诉我这是不正确的。毫无疑问,我在这里遗漏了一些简单的东西,但是我如何执行该查询,以便它告诉我 Ls 或 Ws 的最长连续结果?

【问题讨论】:

您使用哪些列/列来标识“单个团队”? @seahawk 整个表格是一个球队的结果的集合——“gf”列包含该球队的进球数,而“ga”是失球数。我确实有一个未显示的“对手”列,因为它与此查询无关(我相信)。是这个意思吗? 请检查我的回答并确认它是否适合您。 我错过了 MAX 功能。我为此感到遗憾。我已经更新了代码。请再次检查。 【参考方案1】:

从您的代码示例扩展而来,以下给出了获胜/平局的运行情况。问题出在“WHERE R.result RE.result”上,它总是为任何不同的结果代码分配不同的分组。在这里,我将该子句(和其他一些子句)更改为将“W”和“D”组合在一起以形成一个代码:

SELECT result, TYPE, MIN(DATE) AS StartDate, MAX(DATE) AS EndDate, COUNT(*) AS Games 
FROM (SELECT result, TYPE, DATE, compfull, (SELECT COUNT(*) 
  FROM resultengine R 
  WHERE IF(R.result IN ('W','D'),1,0) <> IF(RE.result IN ('W','D'),1,0)
  AND R.date <= RE.date) AS RunGroup
FROM resultengine RE) A WHERE result IN ('W','D') GROUP BY IF(result IN ('W','D'),1,0), RunGroup ORDER BY Games

【讨论】:

感谢@Giles - 这对于计算整体运行非常有用。如果我有一个名为“Venue”的额外列来识别“H”或“A”游戏,是否可以进一步细化查询以计算出最长的 H 游戏或 A 游戏字符串? 我相信是的,从你所说的我想你需要用 venue 和 IN ('W','D') 替换 result = 'H', = 'A ') 或 IN ('H','A') 。 道歉@Giles,我可能并不清楚那里 - 我的意思是计算最长的 Ws 或 Ds(或两者)字符串,其中场地 = H 或 A。因此,是否会出现以下情况将venue = H 作为额外的where 子句添加到查询中? 是的,我想是的,但是您需要 RunGroup 子选择中的子句。 抱歉,您只能继续尝试。这里的诀窍是建立你想要的分组。确定您要计算的组,构建代码,为组内提供一个代码,为组外提供另一个代码(就像我对IF(R.result IN ('W','D'),1,0)) 所做的那样,并将其集成到您的代码块中。我不能继续为您编写代码,你`付给我的钱还不够;)【参考方案2】:

此查询将为您提供单个团队的最大不败序列(该表包含单个团队的数据:

select MAX(final.win_seq_count) from

(Select date,result,gf,ga,type,compfull,
 @seq_count:=if(result="L",0,@seq_count:=@seq_count+1) as win_seq_count,
from resultengine,(select @seq_count:=0) t


order by date) final

注意:代码可能包含小的语法错误。

【讨论】:

以上是关于如何使用 MySQL 计算最长的不败记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何计算每位球员的最长连胜纪录

O(nlogn)最长递增子序列算法,如何输出所求子序列?

MySQL计算最长运行长度

如何使用mysql计算两个日期之间的时间差

MySQL查询以计算文本字段中最长的行

APP开发如何定位才能立于“不败之地”