我有一张足球比赛表:
CREATE TABLE matches(
season NUMBER(4),
matchDate DATE,
homeTeam VARCHAR2(25),
awayTeam VARCHAR2(25),
homeGoals NUMBER(2),
awayGoals NUMBER(2),
totalGoals NUMBER(3));
对于每一行,我希望更新totalGoals
列。 totalGoals
的计算方法是在最近的5场比赛中将得分(homeGoals
+ awayGoals
)的得分加在一起,其中homeTeam
在主场比赛中得分最近的5场比赛得分匹配awayTeam
播放的地方。
它计算仅使用同一赛季的比赛得分。它不包括当前行中的目标。如果任何一支球队在赛季中没有参加所需数量的比赛,totalGoals
仍为空。
我可以使用PL / SQL更新它,但有没有办法只使用SQL?
答案 0 :(得分:2)
如果我了解了您的需求,可以使用analytic functions和windowing clauses执行此操作。
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;
内部选择使用count
和sum
的分析版本以及窗口计算每个季节中每个主场/客场球队的比赛数量和比赛总数条款rows between ...
限制前五个,不包括当前行,我认为这是你想要的。外部选择然后将相关总计一起添加到当前行中的两个团队,但检查两个计数并且如果其中任何一个是< 5.请注意,它只会访问matches
表一次。
在订购前紧跟一个额外的过滤器:
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
您可以使用它来更新匹配行的表,但通常我会根据需要进行计算,以避免潜在的数据完整性错误,可能在视图中。
答案 1 :(得分: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);