LeetCode_sql_day18(1841.联赛信息统计)

描述

表: Teams

+----------------+---------+

| Column Name | Type |

+----------------+---------+

| team_id | int |

| team_name | varchar |

+----------------+---------+

team_id 是该表主键.

每一行都包含了一个参加联赛的队伍信息.

表: Matches

+-----------------+---------+

| Column Name | Type |

+-----------------+---------+

| home_team_id | int |

| away_team_id | int |

| home_team_goals | int |

| away_team_goals | int |

+-----------------+---------+

(home_team_id, away_team_id) 是该表主键.

每一行包含了一次比赛信息.

home_team_goals 代表主场队得球数.

away_team_goals 代表客场队得球数.

获得球数较多的队伍为胜者队伍.

写一段SQL,用来报告联赛信息. 统计数据应使用已进行的比赛来构建,其中 获胜 球队获得 三分 ,而失败球队获得 零分 。如果 打平 ,两支球队都得 一分 。

result 表的每行应包含以下信息:

team_name - Teams 表中的队伍名字matches_played - 主场与客场球队进行的比赛次数.points - 球队获得的总分数.goal_for - 球队在所有比赛中获取的总进球数goal_against - 球队在所有比赛中,他的对手球队的所有进球数goal_diff - goal_for - goal_against.按 points 降序 返回结果表。 如果两队或多队得分相同,则按 goal_diff 降序 排列。 如果仍然存在平局,则以 team_name 按字典顺序 排列它们。

查询的结果格式如下例所示。

示例 1:

输入:

Teams 表:

+---------+-----------+

| team_id | team_name |

+---------+-----------+

| 1 | Ajax |

| 4 | Dortmund |

| 6 | Arsenal |

+---------+-----------+

Matches 表:

+--------------+--------------+-----------------+-----------------+

| home_team_id | away_team_id | home_team_goals | away_team_goals |

+--------------+--------------+-----------------+-----------------+

| 1 | 4 | 0 | 1 |

| 1 | 6 | 3 | 3 |

| 4 | 1 | 5 | 2 |

| 6 | 1 | 0 | 0 |

+--------------+--------------+-----------------+-----------------+

输出:

+-----------+----------------+--------+----------+--------------+-----------+

| team_name | matches_played | points | goal_for | goal_against | goal_diff |

+-----------+----------------+--------+----------+--------------+-----------+

| Dortmund | 2 | 6 | 6 | 2 | 4 |

| Arsenal | 2 | 2 | 3 | 3 | 0 |

| Ajax | 4 | 2 | 5 | 9 | -4 |

+-----------+----------------+--------+----------+--------------+-----------+

解释:

Ajax (team_id=1) 有4场比赛: 2败2平. 总分数 = 0 + 0 + 1 + 1 = 2.

Dortmund (team_id=4) 有2场比赛: 2胜. 总分数 = 3 + 3 = 6.

Arsenal (team_id=6) 有2场比赛: 2平. 总分数 = 1 + 1 = 2.

Dortmund 是积分榜上的第一支球队. Ajax和Arsenal 有同样的分数, 但Arsenal的goal_diff高于Ajax, 所以Arsenal在表中的顺序在Ajaxzhi'qian.

数据准备

Create table If Not Exists Teams (team_id int, team_name varchar(20))

Create table If Not Exists Matches

(

home_team_id int,

away_team_id int,

home_team_goals int,

away_team_goals int

)

Truncate table Teams ;

insert into Teams (team_id, team_name)

values ('1', 'Ajax')

insert

into Teams (team_id, team_name)

values ('4', 'Dortmund')

insert into Teams (team_id, team_name)

values ('6', 'Arsenal');

Truncate table Matches;

insert into Matches (home_team_id, away_team_id, home_team_goals, away_team_goals)

values ('1', '4', '0', '1')

insert into Matches (home_team_id, away_team_id, home_team_goals, away_team_goals)

values ('1', '6', '3', '3')

insert into Matches (home_team_id, away_team_id, home_team_goals, away_team_goals)

values ('4', '1', '5', '2')

insert into Matches (home_team_id, away_team_id, home_team_goals, away_team_goals)

values ('6', '1', '0', '0');

分析

①先构造出得分情况

select *,

case

when home_team_goals > away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals < away_team_goals then 0

end as home_team_points,

case

when home_team_goals < away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals > away_team_goals then 0

end as away_team_points

from Matches

②然后分别计算球队比赛次数(主队的次数+客队的次数)、球队总得分(主队时的得分+客队时的得分)、球队总进球数(主队时的总进球数+客队时的总进球数)、对手总进球数(作为主队时对手作为客队的进球数+作为客队时对手作为主队的总进球数)

with t1 as (select *,

case

when home_team_goals > away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals < away_team_goals then 0

end as home_team_points,

case

when home_team_goals < away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals > away_team_goals then 0

end as away_team_points

from Matches)

select distinct team_name,

(select count(1) from t1 where home_team_id = Matches.home_team_id or away_team_id =Matches.home_team_id) as matches_played,

(select sum(home_team_points) from t1 where home_team_id = Matches.home_team_id) +

(select sum(away_team_points) from t1 where away_team_id = Matches.home_team_id) as points,

(select sum(home_team_goals) from t1 where home_team_id = Matches.home_team_id) +

(select sum(away_team_goals) from t1 where away_team_id = Matches.home_team_id) as goal_for,

(select sum(away_team_goals) from t1 where home_team_id = Matches.home_team_id) +

(select sum(home_team_goals) from t1 where away_team_id = Matches.home_team_id) as goal_against

from matches , teams where matches.home_team_id = teams.team_id

union

select distinct team_name,

(select count(1) from t1 where away_team_id = Matches.away_team_id or home_team_id =Matches.away_team_id) as matches_played,

(select ifnull(sum(home_team_points),0 ) from t1 where home_team_id = Matches.away_team_id) +

(select ifnull(sum(away_team_points),0) from t1 where away_team_id = Matches.away_team_id) as points,

(select ifnull(sum(home_team_goals),0) from t1 where home_team_id = Matches.away_team_id) +

(select ifnull(sum(away_team_goals),0) from t1 where away_team_id = Matches.away_team_id) as goal_for,

(select ifnull(sum(away_team_goals),0) from t1 where home_team_id = Matches.away_team_id) +

(select ifnull(sum(home_team_goals),0) from t1 where away_team_id = Matches.away_team_id) as goal_against

from matches , teams where matches.away_team_id = teams.team_id

③基于上述结果 求goal_diff并且按照题目要求排序

select team_name,

matches_played,

points,

goal_for,

goal_against

,(goal_for-goal_against) as goal_diff from t2

order by points desc,goal_diff desc,team_name desc;

图解:

输入home_team_idaway_team_idhome_team_goalsaway_team_goalshome_team_pointsaway_team_pointsteam_idteam_name1401034Dortmund1633111Ajax4152306Arsenal610011分别求出各队作为

主队和客队时的分数、球数结果team_namematches_playedpointsgoal_forgoal_against结果(最终)Dortmund2662主队的+客队的主队的+客队的主队的+客队的主队的+客队的主队的+客队的Arsenal2233Ajax4259在此基础上求出goal_diffteam_namematches_playedpointsgoal_forgoal_againstgoal_diffDortmund26624Arsenal22330Ajax4259-4

代码

with t1 as (select *,

case

when home_team_goals > away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals < away_team_goals then 0

end as home_team_points,

case

when home_team_goals < away_team_goals then 3

when home_team_goals = away_team_goals then 1

when home_team_goals > away_team_goals then 0

end as away_team_points

from Matches)

, t2 as (

select home_team_id,

(select count(1) from t1 where home_team_id = Matches.home_team_id or away_team_id =Matches.home_team_id) as matches_played,

(select sum(home_team_points) from t1 where home_team_id = Matches.home_team_id) +

(select sum(away_team_points) from t1 where away_team_id = Matches.home_team_id) as points,

(select sum(home_team_goals) from t1 where home_team_id = Matches.home_team_id) +

(select sum(away_team_goals) from t1 where away_team_id = Matches.home_team_id) as goal_for,

(select sum(away_team_goals) from t1 where home_team_id = Matches.home_team_id) +

(select sum(home_team_goals) from t1 where away_team_id = Matches.home_team_id) as goal_against

# goal_for-goal_against as goal_diff

from matches

union all

(select away_team_id,

(select count(1) from t1 where away_team_id = Matches.away_team_id or home_team_id =Matches.away_team_id) as matches_played,

(select sum(away_team_points) from t1 where away_team_id = Matches.away_team_id) +

(select sum(home_team_points) from t1 where home_team_id = Matches.away_team_id) as points,

(select sum(home_team_goals) from t1 where home_team_id = Matches.away_team_id) +

(select sum(away_team_goals) from t1 where away_team_id = Matches.away_team_id) as goal_for,

(select sum(away_team_goals) from t1 where home_team_id = Matches.away_team_id) +

(select sum(home_team_goals) from t1 where away_team_id = Matches.away_team_id) as goal_against

from Matches)

)

select distinct (select team_name from teams where team_id=t2.home_team_id)team_name,

matches_played,

points,

goal_for,

goal_against

,(goal_for-goal_against) as goal_diff from t2

order by points desc,goal_diff desc,team_name;

总结

最后要考虑到有的球队只有客队场 所以使用union 既要关联到主队id又要关联到客队id

热门