1

我有一个足球结果表:

    CREATE TABLE matches(
    season NUMBER(4),
    matchDate DATE,
    homeTeam VARCHAR2(25),
    awayTeam VARCHAR2(25),
    homeGoals NUMBER(2),
    awayGoals NUMBER(2),
    totalGoals NUMBER(3));

对于每一行,我希望更新totalGoals列。计算方法是将最近 5 场主场比赛totalGoals的进球数 ( homeGoals+ awayGoals) 与最近5 场客场比赛的进球数相加。homeTeamawayTeam

它仅使用同一赛季的比赛来计算进球数。它不包括当前行的进球数。如果任何一支球队在赛季中没有参加规定的比赛次数,则totalGoals保持为 NULL。

我可以使用 PL/SQL 来更新它,但是有没有办法只使用 SQL 来做到这一点?

4

2 回答 2

2

如果我了解您想要什么,您可以使用分析函数窗口子句来做到这一点。

select season, matchdate, hometeam, awayteam, homegoals, awaygoals,
    case when home_cnt >= 5 and away_cnt >= 5 then
        home_tot + away_tot
    else null end as totalgoals
from (
    select season, matchdate, hometeam, awayteam, homegoals, awaygoals,
        count(*) over (partition by season, hometeam
            order by matchdate
            rows between 5 preceding and 1 preceding) as home_cnt,
        sum(homegoals + awaygoals) over (partition by season, hometeam
            order by matchdate
            rows between 5 preceding and 1 preceding) as home_tot,
        count(*) over (partition by season, awayteam
            order by matchdate
            rows between 5 preceding and 1 preceding) as away_cnt,
        sum(homegoals + awaygoals) over (partition by season, awayteam
            order by matchdate
            rows between 5 preceding and 1 preceding) as away_tot
    from matches
)
order by season, matchdate, hometeam, awayteam;

内部选择使用 和 的解析版本计算每个赛季中每个主队/客队的比赛次数和总进球数countsum并且窗口子句rows between ...将两者限制为前五个,不包括当前行,我认为这就是你想要的。然后,外部选择将当前行中两个团队的相关总数相加,但会检查两个计数,如果其中一个小于 5,则将总数留空。请注意,它只命中matches表一次。

在 order-by 之前有一个额外的过滤器:

where season = 2012 and homeTeam = 'Norwich' and awayteam = 'Aston Villa'

... 你得到:

    SEASON MATCHDATE HOMETEAM                  AWAYTEAM                   HOMEGOALS  AWAYGOALS TOTALGOALS
---------- --------- ------------------------- ------------------------- ---------- ---------- ----------
      2012 13-MAY-12 Norwich                   Aston Villa                        2          0         30

您可以使用它来更新匹配行的表,但通常我会根据需要计算它以避免潜在的数据完整性错误,可能在视图中。

于 2012-06-16T15:40:44.290 回答
0

我在 MySQL 上尝试了以下操作,但失败并显示“错误代码:1093。您无法在 FROM 子句中指定目标表 'm' 进行更新”。

也许你可以用 Oracle 试试。您必须用 Oracle 限制行数的特定方式替换“limit 0,5”子句。我认为他们使用“rownum < 6”。

update matches m
  set totalGoals = (select sum(homeGoals) + sum(awayGoals) 
                      from matches
                      where homeTeam = m.homeTeam
                        and season = m.season
                        and matchDate < m.matchDate
                      having count(matchDate) > 4
                      order by matchDate limit 0,5) +
                   (select sum(homeGoals) + sum(awayGoals) 
                      from matches
                      where awayTeam = m.awayTeamm
                        and season = m.season
                        and matchDate < m.matchDate
                      having count(matchDate) > 4
                      order by matchDate limit 0,5);
于 2012-06-16T12:45:45.873 回答