Conditional increment of values in two rows after insert in MySQL
I currently have the following three tables in a football db:
teams(name)
season(name, beginning, end)
game(id, Date, season, hometeam, awayteam, HomeTeamScore, AwayTeamScore)
(hometeam, awayteam and season are foreign keys)
Now I'd like to have a new table where I keep track about the goals scored and conceded from every team, as well as their points (one for each draw and three for each win) in every season. This would make it possible to easily get rankings.
I have thought about making a table like this:
stats(season, team, goalsscored, goalsconcedded, points)
Then I would also update it every time a new game is inserted. This table would contain one row for each team+season combination. I am not sure this is the best solution, since I know I am introducing a redundancy, but since this information needs to be calculated often I think it might be useful. I'd like to create a trigger where this information is updated, but do not really know how to do this: I would have to update two rows in the stats table depending on which teams are playing that game, and depending on the fact that they are playing home or away I need to update those with different values.
Ideally, this trigger should create an entry in this new table if the team has not yet been inserted for the season the game is referring to, but I am not even sure such conditions are possible in MySQL. I know I have not provided any test I have done, but this is because I really can't find similar requests online (or more generally to be able to query the information requested easily).
Also, I am open to better ideas of how to deal with this situation.
Much easier than maintaining redundant data with triggers is to just have a view; this is just a basic sum of a union:
create view stats as (
select season, team, sum(goalsscored) goalsscored, sum(goalsconcedded) goalsconcedded, sum(points) points
from (
select season, hometeam team, HomeTeamScore goalsscored, AwayTeamScore goalsconcedded,
case when HomeTeamScore > AwayTeamScore then 3 when HomeTeamScore=AwayTeamScore then 1 else 0 end points
from game
union all
select season, awayteam team, AwayTeamScore goalsscored, HomeTeamScore goalsconcedded,
case when AwayTeamScore > HomeTeamScore then 3 when AwayTeamScore=HomeTeamScore then 1 else 0 end points
from game
) games
group by season, team
);
I think you should consider something like this:
Teams(id,name)
Seasons(id, year,begin_date,end_date)
Games(id, date, season (foreign key), hometeam (foreign key), awayteam (foreign key), HomeTeamScore, AwayTeamScore)
This is also sub-optimal. In my humble opinion you could do better like this
Teams(id,name)
Seasons(id, year,begin_date,end_date)
Matches(id, date, season (foreign key), home_team (foreign key), away_team (foreign key))
Goals(id,team,game,player?)
Goal table will be used to register every goal and then you can construct the match results from there avoiding "HomeTeamScore" and "AwayTeamScore" fields.
As for Stats table you need to know who won the points so let's stick to our last table set:
Teams(id,name)
Seasons(id, year,begin_date,end_date)
Matches(id, date, season (foreign key), home_team (foreign key), away_team (foreign key), status)
Goals(id,team,game,player?)
Status field value in Matches can be: ['1','X','2']
- 1 - Home team winning
- X - Tie match
- 2 - Away team winning
This way you can easily have everything to calculate your stats with, for example for a team having 12 as ID:
Select * from Matches where home_team = 12 and result = '1';
Select * from Matches where away_team = 12 and result = '2';
Select * from Matches where home_team = 12 or away_team=12 and result='X';
You can use this as a starting point to build a slightly more complex query using group by and group functions to calculate team stats. Once you managed to create a query like this I suggest to use a view
By the way these you want to perform are not heavy queries and you don't necessarily need triggers, just think about good database design first!