Leetcode1212. 查询球队积分(中等)

题目
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             |
+------------+--------------+---------------+

创建数据

CREATE TABLE Teams(
team_id INT,
team_name VARCHAR(20));

INSERT INTO Teams VALUE(10, 'Leetcode FC'),(20, 'NewYork FC'),
(30, 'Atlanta FC'),
(40, 'Chicago FC'),
(50, 'Toronto FC');


CREATE TABLE Matches(
match_id   INT,
host_team  INT,
guest_team INT,
host_goals INT,
guest_goals INT);

INSERT INTO Matches VALUE(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);

解答
先分别查主客队得到的分数

-- 主队的得分
SELECT M.`host_team`, IF(M.`host_goals`>M.`guest_goals`,3,IF(M.`host_goals`=M.`guest_goals`, 1, 0)) AS points
FROM Matches AS M;

-- 客队得分
SELECT M1.`guest_team`, IF(M1.`guest_goals`>M1.`host_goals`,3,IF(M1.`guest_goals`=M1.`host_goals`, 1, 0)) AS points
FROM Matches AS M1;

合并

(SELECT M.`host_team`, IF(M.`host_goals`>M.`guest_goals`,3,IF(M.`host_goals`=M.`guest_goals`, 1, 0)) AS points
FROM Matches AS M)
UNION ALL
(SELECT M1.`guest_team`, IF(M1.`guest_goals`>M1.`host_goals`,3,IF(M1.`guest_goals`=M1.`host_goals`, 1, 0)) AS points
FROM Matches AS M1);

对team分组 求出每队的得分和

SELECT all_point.team, SUM(all_point.points)
FROM ((SELECT M.`host_team` AS team, IF(M.`host_goals`>M.`guest_goals`,3,IF(M.`host_goals`=M.`guest_goals`, 1, 0)) AS points
FROM Matches AS M)
UNION ALL
(SELECT M1.`guest_team` AS team, IF(M1.`guest_goals`>M1.`host_goals`,3,IF(M1.`guest_goals`=M1.`host_goals`, 1, 0)) AS points
FROM Matches AS M1)) AS all_point
GROUP BY all_point.team;

和teams表合并 进行排序即可

SELECT T.`team_name`, IFNULL(team_point.num_points,0) AS num_points
FROM Teams AS T
LEFT JOIN (SELECT all_point.team, SUM(all_point.points) AS num_points 
FROM ((SELECT M.`host_team` AS team, IF(M.`host_goals`>M.`guest_goals`,3,IF(M.`host_goals`=M.`guest_goals`, 1, 0)) AS points
FROM Matches AS M)
UNION ALL
(SELECT M1.`guest_team` AS team, IF(M1.`guest_goals`>M1.`host_goals`,3,IF(M1.`guest_goals`=M1.`host_goals`, 1, 0)) AS points
FROM Matches AS M1)) AS all_point
GROUP BY all_point.team) AS team_point
ON T.`team_id` = team_point.team
ORDER BY num_points DESC, T.`team_name` ASC;

别的解答
类似地

首先通过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

这一种也很好理解


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

你可能感兴趣的:(Leetcode1212. 查询球队积分(中等))