SQL:每支球队下一场比赛的最小休息时间

问题描述 投票:1回答:3

您好,这很棘手,我很难挣扎。这超出了我的正常SQL技能:-)这是我面临的问题。

我有一个游戏计划。基本结构如下所示:

ID     League     GameDay     GameTime    HomeTeam     AwayTeam
1        1       16.09.2018    10:00         A            B
2        1       16.09.2018    10:00         C            D
3        1       16.09.2018    14:00         E            F
4        1       16.09.2018    14:00         A            C
5        1       16.09.2018    17:00         B            D
6        1       16.09.2018    17:00         F            A
7        1       17.09.2018    10:00         E            D
8        1       17.09.2018    10:00         C            B
----> This goes on till league 6

我现在需要查询每个团队每天的最小休息时间(以及每个联盟,但团队名称是唯一的)。所以在上面的示例中,A队在16.09.2018的最短休息时间为3小时(比赛从17:00减去比赛从14:00开始)。

经过几次尝试后,我想我已经意识到我不能在一个查询中这样做,所以我将其分解为一个团队。并创建了一些具有以下结果的查询(我在查询中只选择了HomeTeam,然后选择了AwayTeam并联合了这两个):

League      GameDay     GameTime       Team
  1        16.09.2018    10:00          A
  1        16.09.2018    14:00          A
  1        16.09.2018    17:00          A
  1        16.09.2018    10:00          A
  1        16.09.2018    10:00          B
  1        16.09.2018    17:00          B
  1        17.09.2018    10:00          B
---> And so on with the other teams

我感觉我接近理想的结果,但最后一步是缺少 - .-

sql database ms-access ms-access-2016
3个回答
1
投票

这是一个真正的痛苦。首先,您需要一个包含每个团队一列的所有游戏的列表:

select id, league, hometeam as team, gameday, gametime
from gameplan
union all
select id, league, awayteam as team, gameday, gametime
from gameplan;

然后,您需要引入之前的游戏时间,计算日期时间差异和聚合。

您可以使用相关子查询来获取以前的日期/时间:

select gp.*,
       (select max(gp2.dametime)
        from gameplan as gp2
        where gp.gameday = gp2.gameday and
              gp.team in (gp2.hometeam, gp2.awayteam) and
              gp2.gametime < gp.gametime
       ) as prev_gametime
from (select id, league, hometeam as team, gameday, gametime
      from gameplan
      union all
      select id, league, awayteam as team, gameday, gametime
      from gameplan
     ) as gp;

最后,您想要最小的差异:

select league, team, gamedate,
       min(datediff("minute", prev_gametime, gametime)) as minimum_break_length
from (select gp.*,
             (select max(gp2.gametime)
              from gameplan as gp2
              where gp.gameday = gp2.gameday and
                    gp.team in (gp2.hometeam, gp2.awayteam) and
                    gp2.gametime < gp.gametime
             ) as prev_gametime
      from (select id, league, hometeam as team, gameday, gametime
            from gameplan
            union all
            select id, league, awayteam as team, gameday, gametime
            from gameplan
           ) as gp
      ) as gp
group by league, team, gamedate;

1
投票

一种选择是在团队和游戏日使用内部联接的查询,然后使用以下内容计算每个检索记录的时间差:

  SELECT GP1.HOMETEAM AS TEAM, GP1.GAMEDAY AS GAMEDAY, 
         CASE WHEN GP1.GAMETIME>GP2.GAMETIME THEN TIMEDIFF(GP1.GAMETIME, GP2.GAMETIME) ELSE TIMEDIFF(GP2.GAMETIME, GP1.GAMETIME) END AS TIMEDIFF
  FROM GAMEPLAN GP1 
    INNER JOIN GAMEPLAN GP2 
      ON (GP1.HOMETEAM=GP2.HOMETEAM OR GP1.HOMETEAM=GP2.AWAYTEAM) 
          AND GP1.GAMEDAY=GP2.GAMEDAY 
          AND GP1.GAMETIME!=GP2.GAMETIME

这将为每个家庭团队产生一些记录(因为它将计算同一天团队在同一天玩的其他游戏的差异)。此外 - 只有这一点,任何从未在家庭队列表中的队伍都将在结果集中丢失。因此,需要一个联合来覆盖那些(类似于上面的),然后查询只获得具有最小时间差的结果:

SELECT MIN(TIMEDIFF), TEAM, GAMEDAY FROM (
  SELECT GP1.HOMETEAM AS TEAM, GP1.GAMEDAY AS GAMEDAY, 
         CASE WHEN GP1.GAMETIME>GP2.GAMETIME THEN TIMEDIFF(GP1.GAMETIME, GP2.GAMETIME) ELSE TIMEDIFF(GP2.GAMETIME, GP1.GAMETIME) END AS TIMEDIFF
  FROM GAMEPLAN GP1 
    INNER JOIN GAMEPLAN GP2 
      ON (GP1.HOMETEAM=GP2.HOMETEAM OR GP1.HOMETEAM=GP2.AWAYTEAM) 
          AND GP1.GAMEDAY=GP2.GAMEDAY 
          AND GP1.GAMETIME!=GP2.GAMETIME
UNION
  SELECT GP1.AWAYTEAM AS TEAM, GP1.GAMEDAY AS DAY,
         CASE WHEN GP1.GAMETIME>GP2.GAMETIME THEN TIMEDIFF(GP1.GAMETIME, GP2.GAMETIME) ELSE TIMEDIFF(GP2.GAMETIME, GP1.GAMETIME) END AS TIMEDIFF
  FROM GAMEPLAN GP1 
    INNER JOIN GAMEPLAN GP2 
      ON (GP1.AWAYTEAM=GP2.HOMETEAM OR GP1.AWAYTEAM=GP2.AWAYTEAM) 
          AND GP1.GAMEDAY=GP2.GAMEDAY 
          AND GP1.GAMETIME!=GP2.GAMETIME) T
  GROUP BY TEAM, GAMEDAY;

请注意 - 我不完全确定'timediff'功能是否会像MS-ACCESS那样工作;你可能需要重温这一点。


1
投票

它不会在大数据上执行,但它应该工作:

首先它与家庭和客队结合,然后它加入后来的比赛,最终得到最小的差异:

select team, gameday, min(breaktime) from
  (select t.team, t.gameday, g.gametime - t.gametime as breaktime from 
    (select id, league, gameday, gametime, hometeam as team from gameplan
    union 
    select id, league, gameday, gametime, awayteam as team from gameplan) t 
    join gameplan g on t.team in (g.hometeam , g.awayteam) and t.gameday = g.gameday and t.gametime < g.gametime ) breaks
group by team, gameday
© www.soinside.com 2019 - 2024. All rights reserved.