TypechoJoeTheme

Toasobi的博客

最后一个能进入巴士的人(计算前一行某列值与当前行某列值之和)

本文最后更新于2023年09月17日,已超过367天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!
  • 题目:

表: Queue

Column NameType
person_idint
person_namevarchar
weightint
turnint

person_id 是这个表具有唯一值的列。
该表展示了所有候车乘客的信息。
表中 person_id 和 turn 列将包含从 1 到 n 的所有数字,其中 n 是表中的行数。
turn 决定了候车乘客上巴士的顺序,其中 turn=1 表示第一个上巴士,turn=n 表示最后一个上巴士。
weight 表示候车乘客的体重,以千克为单位。

有一队乘客在等着上巴士。然而,巴士有1000 千克 的重量限制,所以其中一部分乘客可能无法上巴士。

编写解决方案找出 最后一个 上巴士且不超过重量限制的乘客,并报告 person_name 。题目测试用例确保顺位第一的人可以上巴士且不会超重。

返回结果格式如下所示。

示例 1:

输入:

Queue 表
person_idperson_nameweightturn
5Alice2501
4Bob1755
3Alex3502
6John Cena4003
1Winston5006
2Marie2004
输出:
person_name
John Cena

解释:

为了简化,Queue 表按 turn 列由小到大排序。
TurnIDNameWeightTotal Weight
15Alice250250
23Alex350600
36John Cena4001000(最后一个上巴士)
42Marie2001200(无法上巴士)
54Bob175_
61Winston500_
这道题的难点在于如何计算当前的weight值与上一行的 Total Weight 之和,判断是否大于等于1000;
一开始尝试使用LAG函数,但是LAG函数无法统计表中原本未有的列

  1. 方法1:使用变量
SELECT
    a.person_name
FROM
(SELECT
    turn
    ,person_name
    ,weight
    ,@prev := @prev + weight AS Total
FROM
    Queue,(SELECT @prev := 0) AS Vars
ORDER BY turn
) a
WHERE 
    a.Total <= 1000
ORDER BY a.turn DESC
LIMIT 1;

使用变量记录每一次上车后车中总重,然后嵌套查询,根据该列值进行判断


  1. 方法二:自连接
SELECT a.person_name
FROM Queue a, Queue b
WHERE a.turn >= b.turn
GROUP BY a.person_id HAVING SUM(b.weight) <= 1000
ORDER BY a.turn DESC
LIMIT 1

我们只需要计算出每个人进去后的总和,找到总和小于等于 1000 的最后一个人即可。于是我们可以使用自连接的方法计算直到当前人的重量的总和
我们使用 a 表的 person_id 表示自身,b 表中的数据表示为包括自己在内的所有人。使用查询条件 a.turn >= b.turn 找到所有在他之前以及他自己的重量。再使用 SUM 计算总和并过滤掉大于 1000 的数据

使用自连接,可以限制函数SUM统计到哪一行
朗读
赞(0)
评论 (0)