【问题标题】:Calculate run or streak across years in MySQL在 MySQL 中计算跨年的运行或连续运行
【发布时间】:2012-05-31 19:33:38
【问题描述】:

我正在尝试计算 MySQL 数据库中的连胜记录。我创建了下表来存储赢/输数据:

"year"  "team_id"   "week"  "result"
"2007"  "1"         "1"     "W"
"2007"  "1"         "2"     "L"
"2007"  "1"         "3"     "W"
"2007"  "1"         "4"     "W"
"2007"  "1"         "5"     "W"
"2007"  "1"         "6"     "W"
"2007"  "1"         "7"     "W"
"2007"  "1"         "8"     "W"
"2007"  "1"         "9"     "W"
"2007"  "1"         "10"    "L"
. . .

此数据跨越 12 个团队的 4 年,每年 13-16 周。

为了计算连胜次数,我使用以下查询:

SELECT
    team_id,
    result,
    year,
    MIN(week) as StartDate, 
    MAX(week) as EndDate, 
    COUNT(*) as Games
FROM (
    SELECT
        year,
        week,
        team_id,
        result,
        (   SELECT
                COUNT(*) 
            FROM
                win_loss_temp wl2 
            WHERE
                wl1.team_id = wl2.team_id
                and wl2.result <> wl1.result
                and wl2.year <= wl1.year
                AND wl2.week <= wl1.week) as rungroup
    FROM
        win_loss_temp wl1) A
WHERE result = 'W'
GROUP BY year, team_id, result, rungroup
ORDER BY Games desc
LIMIT 15;

这给出了以下结果:

team_id    result    year    StartDate    EndDate    Games
----------------------------------------------------------
5          W         2007    1            12         12
1          W         2007    3            9          7
5          W         2008    2            7          6
. . .

这是正确/预期的输出...在一个给定的年份内。

我的问题跨越多年。假设一支球队在 2007 年以 3 连胜结束,然后赢得了 2008 年的前 4 场比赛。这应该记录为总共 7 连胜(7 胜不记输)。但到目前为止,我无法弄清楚如何修改上述查询以适应跨年。

我什至尝试在表中创建一个新字段,该字段将年份与星期连接起来(例如,2007.13 代表 2007 年第 13 周),但使用该字段而不是单独使用年份和星期没有成功。给出了时髦的结果。

谢谢。

【问题讨论】:

    标签: mysql


    【解决方案1】:
    SELECT
        team_id,
        result,
        year,
        MIN(CONCAT(year,week)) as StartDate, 
        MAX(CONCAT(year,week)) as EndDate, 
        COUNT(*) as Games
    

    【讨论】:

      【解决方案2】:

      重新审视这个以修改我以前不完整(直到现在我还不知道)的答案。感谢this external resource,它完全解决了我的问题,我能够调整查询以完美地满足我的特定需求。

      首先,我创建了一个视图run_groups,定义如下:

      select
          `GR`.`team_id` AS `team_id`,
          ((`GR`.`year` * 100) + `GR`.`week`) AS `GameDate`,
          `GR`.`result` AS `Result`, (
              select
                  count(0)
              from
                  `jaddl`.`game_results` `G`
              where
                  ((`G`.`result` <> `GR`.`result`) and
                  (`G`.`team_id` = `GR`.`team_id`) and
                  (`G`.`playoffs` = `GR`.`playoffs`) and
                  (((`G`.`year` * 100) + `G`.`week`) <= ((`GR`.`year` * 100) + `GR`.`week`)))) AS `RunGroup`
      from
          `jaddl`.`game_results` `GR`
      where
          (`GR`.`playoffs` = 0)
      

      然后我可以利用该视图来创建另一个视图,这给了我最终的结果,我可以查询这些结果以用于数据挖掘目的......我的最终游戏。

      select
          `run_groups`.`team_id` AS `team_id`,
          `run_groups`.`Result` AS `Result`,
          min(`run_groups`.`GameDate`) AS `StartDate`,
          max(`run_groups`.`GameDate`) AS `EndDate`,
          count(0) AS `Games`
      from
          `jaddl`.`run_groups`
      group by `run_groups`.`team_id`, `run_groups`.`Result`, `run_groups`.`RunGroup`
      order by count(0) desc, `run_groups`.`Result` desc, min(`run_groups`.`GameDate`)
      

      这样输出数据:

      team_id  Result  StartDate  EndDate  Games  
            1      -1     201507   201606     13  
            7      -1     201603   201702     13  
            5       1     200701   200712     12  
            1      -1     201202   201213     12  
            2       1     200908   201005     11  
           12       1     201209   201305     10  
            5       1     201401   201410     10  
            4      -1     200813   200908      9  
           11      -1     201112   201207      9  
      

      1 中的result 是胜利,-1 是失败。)瞧!我需要查询所有与条纹相关的统计数据的数据集。向@eggyal 致敬,他提出了使用year*100+week 而不是将年份和周与前导零作为字符串连接的出色建议。

      【讨论】:

      • 哦。我在看到您发布此内容之前发表了评论。是的,这几乎肯定是你的问题。最好只使用整数而不是摆弄字符串和填充:YEAR*100 + WEEK
      • @eggyal 伟大的思想都一样。 :) 但是请参阅我在此答案中的最新编辑...问题尚未完全解决。
      • 是的,将您的子选择更改为同时选择 concat(year, week) 并从您的选择和分组中删除年份。
      猜你喜欢
      • 1970-01-01
      • 2016-12-03
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 2019-11-10
      相关资源
      最近更新 更多