Problem#
Table: Teams
+---------------+----------+
| Column Name | Type |
+---------------+----------+
| team_id | int |
| team_name | varchar |
+---------------+----------+
team_id is the column with unique values 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 column of unique values 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 (i.e., Scored more goals than the opponent team).
- A team receives one point if they draw a match (i.e., Scored the same number of goals as the opponent team).
- A team receives no points if they lose a match (i.e., Scored fewer goals than the opponent team).
Write a solution that selects the team_id
, team_name
and num_points
of each team in the tournament after all described matches.
Return the result table ordered by num_points
in decreasing order. In case of a tie, order the records by team_id
in increasing order.
The result format is in the following example.
Examples#
Example 1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
Input:
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 |
+------------+--------------+---------------+-------------+--------------+
Output:
+------------+--------------+---------------+
| 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 |
+------------+--------------+---------------+
|
Solution#
Approach#
We need to calculate the total points for each team based on match results. For each match, the host and guest teams get points according to the result (win: 3, draw: 1, loss: 0). We aggregate the points for each team and join with the Teams table to get the team names.
Code#
MySQL#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
SELECT t.team_id, t.team_name, COALESCE(SUM(s.points), 0) AS num_points
FROM Teams t
LEFT JOIN (
SELECT host_team AS team_id,
CASE
WHEN host_goals > guest_goals THEN 3
WHEN host_goals = guest_goals THEN 1
ELSE 0
END AS points
FROM Matches
UNION ALL
SELECT guest_team AS team_id,
CASE
WHEN guest_goals > host_goals THEN 3
WHEN guest_goals = host_goals THEN 1
ELSE 0
END AS points
FROM Matches
) s ON t.team_id = s.team_id
GROUP BY t.team_id, t.team_name
ORDER BY num_points DESC, t.team_id ASC;
|
Oracle#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
SELECT t.team_id, t.team_name, NVL(SUM(s.points), 0) AS num_points
FROM Teams t
LEFT JOIN (
SELECT host_team AS team_id,
CASE
WHEN host_goals > guest_goals THEN 3
WHEN host_goals = guest_goals THEN 1
ELSE 0
END AS points
FROM Matches
UNION ALL
SELECT guest_team AS team_id,
CASE
WHEN guest_goals > host_goals THEN 3
WHEN guest_goals = host_goals THEN 1
ELSE 0
END AS points
FROM Matches
) s ON t.team_id = s.team_id
GROUP BY t.team_id, t.team_name
ORDER BY num_points DESC, t.team_id ASC;
|
PostgreSQL#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
SELECT t.team_id, t.team_name, COALESCE(SUM(s.points), 0) AS num_points
FROM Teams t
LEFT JOIN (
SELECT host_team AS team_id,
CASE
WHEN host_goals > guest_goals THEN 3
WHEN host_goals = guest_goals THEN 1
ELSE 0
END AS points
FROM Matches
UNION ALL
SELECT guest_team AS team_id,
CASE
WHEN guest_goals > host_goals THEN 3
WHEN guest_goals = host_goals THEN 1
ELSE 0
END AS points
FROM Matches
) s ON t.team_id = s.team_id
GROUP BY t.team_id, t.team_name
ORDER BY num_points DESC, t.team_id ASC;
|
Explanation#
We use a UNION ALL
to collect points for both host and guest teams for each match, then sum the points for each team. Teams with no matches get 0 points. The result is ordered by points descending, then team_id ascending.
Complexity#
- ⏰ Time complexity:
O(M + N)
where M is the number of teams and N is the number of matches.
- 🧺 Space complexity:
O(M)
for storing the points per team.