订阅更新

旅行者里程排行:没出行的也要显示 0

SQL 实战 123 题 · 第 105 题 简单 约 2 分钟读完

LeetCode 1407 · LEFT JOIN 求和、零值、按 ID 分组

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

用户 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) 结果相同,后者少做一些计算。
刷题进度保存在当前浏览器