LeetCode 1212. Team Scores in Football Tournament
Table: Teams
+---------------+----------+
| Column Name | Type |
+---------------+----------+
| team_id | int |
| team_name | varchar |
+---------------+----------+
team_id is the primary key of this table.
Each row of this table represents a single football team.
Table: Matches
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| match_id | int |
| host_team | int |
| guest_team | int |
| host_goals | int |
| guest_goals | int |
+---------------+---------+
match_id is the primary key of this table.
Each row is a record of a finished match between two different teams.
Teams host_team and guest_team are represented by their IDs in the teams table (team_id) and they scored host_goals and guest_goals goals respectively.
You would like to compute the scores of all teams after all matches. Points are awarded as follows:
- A team receives three points if they win a match (Score strictly more goals than the opponent team).
- A team receives one point if they draw a match (Same number of goals as the opponent team).
- A team receives no points if they lose a match (Score less goals than the opponent team).
Write an SQL query that selects the team_id, team_name and num_points of each team in the tournament after all described matches. Result table should be ordered by num_points (decreasing order). In case of a tie, order the records by team_id (increasing order).
The query result format is in the following example:
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 |
+------------+--------------+---------------+
简要翻译:
两张表:队伍表和比赛表。统计队伍积分,胜3分,平1分,负0分,查询个队伍排名榜,查询结果先按积分降序,然后按team_id升序排列。
建表语句:
CREATE TABLE Teams (
team_id INT ,
team_name VARCHAR (20)
) ;
CREATE TABLE Matches (
match_id INT ,
host_team INT ,
guest_team INT ,
host_goals INT,
guest_goals INT
) ;
INSERT INTO Teams (team_id, team_name)
VALUES
(10, 'Leetcode FC') ;
INSERT INTO Teams (team_id, team_name)
VALUES
(20, 'NewYork FC') ;
INSERT INTO Teams (team_id, team_name)
VALUES
(30, 'Atlanta FC') ;
INSERT INTO Teams (team_id, team_name)
VALUES
(40, 'Chicago FC') ;
INSERT INTO Teams (team_id, team_name)
VALUES
(50, 'Toronto FC') ;
INSERT INTO Matches (
match_id,
host_team,
guest_team,
host_goals,
guest_goals
)
VALUES
(1, 10, 20, 3, 0) ;
INSERT INTO Matches (
match_id,
host_team,
guest_team,
host_goals,
guest_goals
)
VALUES
(2, 30, 10, 2, 2) ;
INSERT INTO Matches (
match_id,
host_team,
guest_team,
host_goals,
guest_goals
)
VALUES
(3, 10, 50, 5, 1) ;
INSERT INTO Matches (
match_id,
host_team,
guest_team,
host_goals,
guest_goals
)
VALUES
(4, 20, 30, 1, 0) ;
INSERT INTO Matches (
match_id,
host_team,
guest_team,
host_goals,
guest_goals
)
VALUES
(5, 50, 30, 1, 0) ;
SQL思路:
一、查询每场比赛各队伍得分:
# 作为主队的得分统计:
1 SELECT
2 team_id,
3 team_name,
4 IF(
5 host_goals > guest_goals,
6 3,
7 IF(host_goals = guest_goals, 1, 0)
8 ) AS points
9 FROM
10 teams,
11 matches
12 WHERE team_id = host_team;
#作为客队的得分统计
1 SELECT
2 team_id,
3 team_name,
4 IF(
5 host_goals > guest_goals,
6 0,
7 IF(host_goals = guest_goals, 1, 3)
8 ) AS points
9 FROM
10 teams,
11 matches
12 WHERE team_id = guest_team;
二、将上两张表union all ,然后分组聚合查询,然后发现少了没参赛队伍的积分。因此需要left join 。最终查询语句如下
1 SELECT
2 t.team_id,
3 t.team_name,
4 SUM(IFNULL(points,0)) AS num_points
5 FROM
6 teams t LEFT JOIN
7 (
8 SELECT
9 host_team AS team_id,
10 IF(
11 host_goals > guest_goals,
12 3,
13 IF(host_goals = guest_goals, 1, 0)
14 ) AS points
15 FROM
16 matches
17 UNION ALL
18 SELECT
19 guest_team AS team_id,
20 IF(
21 host_goals > guest_goals,
22 0,
23 IF(host_goals = guest_goals, 1, 3)
24 ) AS points
25 FROM
26 matches
27 )temp ON
28 t.team_id = temp.team_id
29 GROUP BY team_id
30 ORDER BY num_points DESC ,team_id ASC ;