28,SQL训练之,力扣,1204. 最后一个能进入巴士的人。经典面试题,最后一个上电梯的人

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用

目录

一,原题力扣链接

二,题干

三,建表语句

四,分析

解法一:开窗函数 sum开窗;

解法二:非等值连接

五,SQL解答

第一种解法,用开窗解答:

第二种解法,用自连接解答

六,验证

七,知识点总结


一,原题力扣链接

. - 力扣(LeetCode)

二,题干

表: Queue

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

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

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

返回结果格式如下所示。

示例 1:

输入:
Queue 表
+-----------+-------------+--------+------+
| person_id | person_name | weight | turn |
+-----------+-------------+--------+------+
| 5         | Alice       | 250    | 1    |
| 4         | Bob         | 175    | 5    |
| 3         | Alex        | 350    | 2    |
| 6         | John Cena   | 400    | 3    |
| 1         | Winston     | 500    | 6    |
| 2         | Marie       | 200    | 4    |
+-----------+-------------+--------+------+
输出:
+-------------+
| person_name |
+-------------+
| John Cena   |
+-------------+
解释:
为了简化,Queue 表按 turn 列由小到大排序。
+------+----+-----------+--------+--------------+
| Turn | ID | Name      | Weight | Total Weight |
+------+----+-----------+--------+--------------+
| 1    | 5  | Alice     | 250    | 250          |
| 2    | 3  | Alex      | 350    | 600          |
| 3    | 6  | John Cena | 400    | 1000         | (最后一个上巴士)
| 4    | 2  | Marie     | 200    | 1200         | (无法上巴士)
| 5    | 4  | Bob       | 175    | ___          |
| 6    | 1  | Winston   | 500    | ___          |
+------+----+-----------+--------+--------------+

三,建表语句

Create table If Not Exists Queue (person_id int, person_name varchar(30), weight int, turn int);
Truncate table Queue;
insert into Queue (person_id, person_name, weight, turn) values ('5', 'Alice', '250', '1');
insert into Queue (person_id, person_name, weight, turn) values ('4', 'Bob', '175', '5');
insert into Queue (person_id, person_name, weight, turn) values ('3', 'Alex', '350', '2');
insert into Queue (person_id, person_name, weight, turn) values ('6', 'John Cena', '400', '3');
insert into Queue (person_id, person_name, weight, turn) values ('1', 'Winston', '500', '6');
insert into Queue (person_id, person_name, weight, turn) values ('2', 'Marie', '200', '4');


insert into Queue (person_id, person_name, weight, turn) values ('5', 'Alice', '25', '1');
insert into Queue (person_id, person_name, weight, turn) values ('4', 'Bob', '15', '5');
insert into Queue (person_id, person_name, weight, turn) values ('3', 'Alex', '30', '2');
insert into Queue (person_id, person_name, weight, turn) values ('6', 'John Cena', '40', '3');
insert into Queue (person_id, person_name, weight, turn) values ('1', 'Winston', '50', '6');
insert into Queue (person_id, person_name, weight, turn) values ('7', 'Marie1', '2000', '7');

四,分析

题解:

表:queue表

字段: 乘客id,乘客姓名,乘客重量,乘客上电梯的顺序

要求,电梯载重只有1000,求出最后一个上电梯的人;

解法一:开窗函数 sum开窗;

用sum,sum开窗 以上电梯排序 ,依次拿到重量

拿到电梯小于等于1000的所有对应的员工的名称

然后倒序,

最后取第一个;

坑点一:如果乘客都不满足1000公斤,倒序最后一个就是上电梯的人;

如果乘客有人满足了1000公斤 那么就是超重的人,这个我们不要了;

所有需要倒序排序 对上电梯的人做个倒序;

1

1

解法二:非等值连接

用表1的上电梯顺序<表2的上电梯顺序

这样最后一个上电梯的trun排序在后面,也就是他和前面的每一个人都做了一个比较,以他分组,他对应的重量就是电梯里面的人的全部重量

后面我们要以 表1的id分组 求表2的重量sum 

或者以表2的id分组 求表1的种类sum 是一个意思

图解来说就是

换言之用官方的话说:假设 Queue 表有 3 条记录,那么自连接后将会有 9 条数据,分别为 (a1 b1),(a1 b2),(a1 b3),(a2 b1),(a2 b2),(a2 b3),(a3 b1),(a3 b2),(a3 b3) 。

然后我们拿到重量小于1000的人的姓名

做一个倒序 根据trun

拿到第一个 也就是最后一个上电梯的人

五,SQL解答

第一种解法,用开窗解答:

with t1 as (
    select *,
         sum(weight) over (order by turn ) so
         from queue
)
select person_name from t1 where t1.so<=1000 order by turn desc limit 1;

第二种解法,用自连接解答

select person_name from queue where person_id in
    (
    select q1.person_id from queue q1 join queue q2
                    where q1.turn>=q2.turn
                    group by q1.person_id having sum(q2.weight)<=1000
           ) order by turn desc  limit 1;

六,验证

七,知识点总结

经典面试题  最后一个上电梯的人

思路一:

1,sum开窗,以上电梯的顺序排序,依次拿到不同的重量

2,重量小于等于1000作为条件,然后拿到他们的名称

3,以上电梯的顺序倒序排序 拿到最后一个登上电梯的人;

--

思路二

1,一自联结 

2,表1 上电梯顺序大于表2 上电梯顺序; 会等值连接

3,从而形成表1的每一条会依次 依次和表2的上电梯的顺序 相互乘;

4,表1中最后一个登录电梯的人,就拿到了前面的全部重量;

然后根据表1的id分组,sum表2的重量;

最后判断重量小于 1000

然后根据trun desc倒序 

拿到第一个 也就是最后一个登录电梯的人

  • 开窗练习 sum函数;
  • 排序连续order by
  • limit 练习

  • 学习:知识的初次邂逅
  • 复习:知识的温故知新
  • 练习:知识的实践应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值