旅行者里程排行:没出行的也要显示 0
LeetCode 1407 · LEFT JOIN 求和、零值、按 ID 分组
面试怎么回答
用户 LEFT JOIN 行程,GROUP BY u.id, u.name,IFNULL(SUM(distance), 0),排序写 travelled_distance DESC, name。分组一定要带主键,只按名字分组会把同名用户合并。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
用户表和行程表(每次行程的用户和距离)。输出每个用户的总里程,没有行程的显示 0;按里程降序,里程相同按名字升序。
表结构
- Users:id(主键)、name
- Rides:id(主键)、user_id、distance
思路
用户表 LEFT JOIN 行程表,按用户分组求和,没有行程的和为 NULL,用 IFNULL 变成 0。分组键要用用户 ID:原解法按 name 分组,两个同名用户的里程会被加到一起。
参考解法
select name,sum(ifnull(distance,0)) travelled_distance
from Users u left join Rides r
on u.id = r.user_id
group by name
order by travelled_distance desc, name
另一种写法:按用户 ID 分组
SELECT u.name, IFNULL(SUM(r.distance), 0) AS travelled_distance
FROM Users u
LEFT JOIN Rides r ON u.id = r.user_id
GROUP BY u.id, u.name
ORDER BY travelled_distance DESC, u.name
易错点
- 按 name 分组会合并同名用户。
SUM(IFNULL(distance, 0))和IFNULL(SUM(distance), 0)结果相同,后者少做一些计算。