1204. 最后一个能进入巴士的人 三种解题思路

文章介绍了如何使用SQL查询来解决一个巴士载客问题,其中要考虑巴士的重量限制和乘客上车顺序。提供了三种方法,包括窗口函数、子查询和内联查询,来找出最后一个能上巴士且不超过重量限制的乘客。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1204. 最后一个能进入巴士的人

地址

1204. 最后一个能进入巴士的人

题目

表: Queue

Column NameType
person_idint
person_namevarchar
weightint
turnint

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

题干

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

写一条 SQL 查询语句找出 最后一个 上巴士且不超过重量限制的乘客,并报告 person_name 。题目测试用例确保顺位第一的人可以上巴士且不会超重。

查询结果格式如下所示。

示例

输入:

Queue 表

person_idperson_nameweightturn
5Alice2501
4Bob1755
3Alex3502
6John Cena4003
1Winston5006
2Marie2004

输出:

person_name
Thomas Jefferson

解释:

为了简化,Queue 表按 turn 列由小到大排序。

TurnIDNameWeightTotal Weight备注
15Alice250250
23Alex350600
36John Cena4001000(最后一个上巴士)
42Marie2001200(无法上巴士)
54Bob175___
61Winston500___

解题

方法一: 窗口函数

  • 在窗口函数中求出所有的累加和
select * ,sum(weight)  over(order by turn)  as sumweight from Queue 

此时结果

person_idperson_nameweightturnsumweight
5Alice2501250
3Alex3502600
6John Cena40031000
2Marie20041200
4Bob17551375
1Winston50061875

所以此时倒序排序找出sumweight小于等于1000 的对应的person id 即为最后结果

  • 此时最终语句为
 select person_name from (
   select * ,sum(weight)  over(order by turn)  as sumweight from Queue 
 ) as a
 where sumweight<=1000
 order by sumweight desc
 limit 1

最终结果

person_name
Thomas Jefferson

解释

窗口函数运算规则
我们没有对窗口函数进行范围限制 默认为 从开始到轮到的位置 求和 即为前一总和前二总和 前三总和。。。

方法二: 子查询

  • 子查询求前n和
select sum(weight) from Queue
where turn <=n

此时结果

为单个前n项的总和

  • 此时在外侧嵌套一层查询
select *
from Queue q1
where (select sum(weight) from Queue where turn <= q1.turn) <= 1000

此时结果

person_idperson_nameweightturn
5Alice2501
3Alex3502
6John Cena4003

解释

在这里插入图片描述

对于限制条件**<= q1.turn**

  • 语句开始时 q1.turn=1
    • 子查询语句求turn<=1的总和
    • 满足小于等于1000
    • 此时turn=1 被选出来
  • q1.turn=2
    • 子查询语句求turn<=2的总和
    • 满足小于等于1000
    • 此时turn=2 被选出来
  • 以此类推
    • q1.turn=4
    • 子查询语句求turn<=4的总和
    • 不满足小于等于1000
    • 此时turn=4 没被选出来
  • 以此类推 得到结果
    最后我们对查出的结果按turn倒序排序取第一个即为最后结果

方法三:内联查询

  • 找出符合条件的每一列数据 根据a.turn>b.turn 得出 每个人进入时的所有人情况
select * from Queue a , Queue b
where a.turn>=b.turn
order by  a.turn

此时结果

person_idperson_nameweightturnperson_idperson_nameweightturn
5Alice25015Alice2501
3Alex35025Alice2501
3Alex35023Alex3502
6John Cena40035Alice2501
6John Cena40036John Cena4003
6John Cena40033Alex3502
2Marie20045Alice2501
2Marie20042Marie2004
2Marie20043Alex3502
2Marie20046John Cena4003
4Bob17552Marie2004
4Bob17556John Cena4003
4Bob17553Alex3502
4Bob17554Bob1755
4Bob17555Alice2501
1Winston50063Alex3502
1Winston50066John Cena4003
1Winston50064Bob1755
1Winston50061Winston5006
1Winston50062Marie2004
1Winston50065Alice2501

分析

在这里插入图片描述
只有turn等于1的人进入公交车 此时总重就为 turn=1
只有turn等于1,2的人进入公交车 此时总重就为 turn=1与turn=2的和
只有turn等于1,2,3 的人进入公交车 此时总重就为 turn=1-3
只有turn等于1,2,3,4的人进入公交车 此时总重就为 turn=1-4
所以只需要对他们按照turn分组求 trun的和 即为前n人上车时的总重

  • 此时对上层结果处理 分组求和
select *, sum(b.weight) from Queue a , Queue b
where a.turn>=b.turn
group by a.turn
order by  a.turn

此时结果

person_idperson_nameweightturnperson_idperson_nameweightturnsum(b.weight)
5Alice25015Alice2501250
3Alex35025Alice2501600
6John Cena40035Alice25011000
2Marie20045Alice25011200
4Bob17555Alice25011375
1Winston50065Alice25011875

所以只需要筛选出小于等于1000的倒序第一即为最后的答案

最终解答

select person_name from(
select a.person_name, sum(b.weight) as weightsum from Queue a , Queue b
where a.turn>=b.turn
group by a.turn
order by  a.turn
) as  a
where weightsum  <=1000
order by weightsum  desc
limit 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值