SQL:每队下一场比赛的最少休息时间
SQL: Minimal break to next game per team
你好,这有点棘手,我正在努力奋斗。这超出了我正常的 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 队在 2018 年 9 月 16 日的最短休息时间为 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
我感觉我接近想要的结果,但缺少最后一步 -.-
一种选择是在团队和比赛日使用带有内部联接的查询,然后计算每个检索到的记录的时间差:
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 上那样工作;您可能需要重新访问它。
它在大数据上表现不佳,但应该可以:
先与主客场并集,再与后面的比赛合并,最后得到最小差值:
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
这是一个真正的痛苦。首先,您需要一个包含每个团队 一个 列的所有游戏的列表:
select id, league, hometeam as team, gameday, gametime
from gameplan
union all
select id, league, awayteam as team, gameday, gametime
from gameplan;
然后,你需要带入之前的游戏时间,计算时间差,并汇总。
你可以使用相关子查询来获取之前的date/time:
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;
你好,这有点棘手,我正在努力奋斗。这超出了我正常的 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 队在 2018 年 9 月 16 日的最短休息时间为 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
我感觉我接近想要的结果,但缺少最后一步 -.-
一种选择是在团队和比赛日使用带有内部联接的查询,然后计算每个检索到的记录的时间差:
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 上那样工作;您可能需要重新访问它。
它在大数据上表现不佳,但应该可以:
先与主客场并集,再与后面的比赛合并,最后得到最小差值:
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
这是一个真正的痛苦。首先,您需要一个包含每个团队 一个 列的所有游戏的列表:
select id, league, hometeam as team, gameday, gametime
from gameplan
union all
select id, league, awayteam as team, gameday, gametime
from gameplan;
然后,你需要带入之前的游戏时间,计算时间差,并汇总。
你可以使用相关子查询来获取之前的date/time:
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;