Table: Teams
+---------------+----------+
| Column Name | Type |
+---------------+----------+
| team_id | int |
| team_name | varchar |
+---------------+----------+
此表的主键是 team_id,表中的每一行都代表一支独立足球队。
Table: Matches
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| match_id | int |
| host_team | int |
| guest_team | int |
| host_goals | int |
| guest_goals | int |
+---------------+---------+
此表的主键是 match_id,表中的每一行都代表一场已结束的比赛,比赛的主客队分别由它们自己的 id 表示,他们的进球由 host_goals 和 guest_goals 分别表示。
积分规则如下:
赢一场得三分;
平一场得一分;
输一场不得分。
写出一条SQL语句以查询每个队的 team_id,team_name 和 num_points。结果根据 num_points 降序排序,如果有两队积分相同,那么这两队按 team_id 升序排序。
查询结果格式如下:
Teams table:
+-----------+--------------+
| team_id | team_name |
+-----------+--------------+
| 10 | Leetcode FC |
| 20 | NewYork FC |
| 30 | Atlanta FC |
| 40 | Chicago FC |
| 50 | Toronto FC |
+-----------+--------------+
Matches table:
+------------+--------------+---------------+-------------+--------------+
| match_id | host_team | guest_team | host_goals | guest_goals |
+------------+--------------+---------------+-------------+--------------+
| 1 | 10 | 20 | 3 | 0 |
| 2 | 30 | 10 | 2 | 2 |
| 3 | 10 | 50 | 5 | 1 |
| 4 | 20 | 30 | 1 | 0 |
| 5 | 50 | 30 | 1 | 0 |
+------------+--------------+---------------+-------------+--------------+
Result table:
+------------+--------------+---------------+
| team_id | team_name | num_points |
+------------+--------------+---------------+
| 10 | Leetcode FC | 7 |
| 20 | NewYork FC | 3 |
| 50 | Toronto FC | 3 |
| 30 | Atlanta FC | 1 |
| 40 | Chicago FC | 0 |
+------------+--------------+---------------+
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/team-scores-in-football-tournament
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
审题:写出一条SQL语句以查询每个队的 team_id,team_name 和 num_points。结果根据 num_points 降序排序,如果有两队积分相同,那么这两队按 team_id 升序排序。
根据进球数,计算比分,最后求和。
思考:首先根据结果对数据加工,算出主队客队的本场比赛积分,然后求所有球队id的比分和。
解题:
方法一:思路:求id,队名,分数。
首先通过union all将比赛结果表,将对两队的结果,联合起来。如果五场比赛,相当于10个球队,将比赛表左右两边对调,就可以是五场比赛的十支球队结果都包含了。
然后通过teams表left join 使得左边肯定多于右边,判断通过on后边的条件对比,右边分组里的每一行通过对比判断积分,求和。
最后按照条件排序即可。
select t.team_id,t.team_name,
sum(case when m.host_goals > m.guest_goals then 3
when m.host_goals = m.guest_goals then 1
else 0 end) num_points
from teams t
left join
(select host_team, guest_team, host_goals, guest_goals
from matches
union all
select guest_team host_team, host_team guest_team, guest_goals host_goals, host_goals guest_goals
from matches) m
on m.host_team = t.team_id
group by t.team_id
order by num_points desc, t.team_id asc
-- 练习
-- left join
-- LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹-- -- 配,则结果为 NULL。
select t.team_id, t.team_name,
sum(case when m.host_goals>m.guest_goals then 3 when m.host_goals = m.guest_goals then 1 else 0 end) num_points from teams t left join
(select host_team, guest_team, host_goals, guest_goals
from matches
union all
select guest_team host_team, host_team guest_team, guest_goals host_goals, host_goals guest_goals
from matches) m
on m.host_team = t.team_id
group by t.team_id
order by num_points desc,t.team_id asc;
方法二:
select t.team_id,t.team_name,sum(
CASE WHEN t.team_id= m.host_team and m.host_goals>m.guest_goals THEN 3
WHEN m.host_goals = m.guest_goals THEN 1
WHEN t.team_id = m.guest_team and m.guest_goals>m.host_goals THEN 3 ELSE 0 END
) as num_points
from Teams t
left join Matches m
on t.team_id=m.host_team or t.team_id=m.guest_team
group by t.team_id
order by num_points desc ,team_id asc
知识点:
UNION 只会选取不同的值。请使用 UNION ALL 来选取重复的值!