暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

单挑力扣(LeetCode)SQL笔试题:2388. 将表中的空值更改为前一个值(难度:中等)

原创 fizz 2023-01-10
1115
题目:2388. 将表中的空值更改为前一个值
(通过次数317 | 提交次数446,通过率71.08%)
表: CoffeeShop+-------------+---------+| Column Name | Type    |+-------------+---------+| id          | int     || drink       | varchar |+-------------+---------+id 是该表的主键。该表中的每一行都显示了订单 id 和所点饮料的名称。一些饮料行为 null。
编写一个 SQL 查询,将 drink 的 null值替换为前面最近一行不为 null的 drink。保证表第一行的 drink 不为 null。返回与输入顺序相同的结果表。
查询结果格式示例如下。示例 1:输入:CoffeeShop 表:+----+------------------+| id | drink |+----+------------------+| 9 | Mezcal Margarita || 6 | null || 7 | null || 3 | Americano || 1 | Daiquiri || 2 | null |+----+------------------+输出: +----+------------------+| id | drink |+----+------------------+| 9 | Mezcal Margarita || 6 | Mezcal Margarita || 7 | Mezcal Margarita || 3 | Americano || 1 | Daiquiri || 2 | Daiquiri |+----+------------------+解释: 对于 ID 6,之前不为空的值来自 ID 9。我们将 null 替换为 “Mezcal Margarita”。对于 ID 7,之前不为空的值来自 ID 9。我们将 null 替换为 “Mezcal Margarita”。对于 ID 2,之前不为空的值来自 ID 1。我们将 null 替换为 “Daiquiri”。请注意,输出中的行与输入中的行相同。
来源:力扣(LeetCode)链接:https://leetcode.cn/problems/change-null-values-in-a-table-to-the-previous-value
#测试数据Create table If Not Exists CoffeeShop (id int, drink varchar(20));
insert into CoffeeShop (id, drink) values ('9', 'Mezcal Margarita');insert into CoffeeShop (id, drink) values ('6', 'None');insert into CoffeeShop (id, drink) values ('7', 'None');insert into CoffeeShop (id, drink) values ('3', 'Americano');insert into CoffeeShop (id, drink) values ('1', 'Daiquiri');insert into CoffeeShop (id, drink) values ('2', 'None');
解题思路:
这道题出的不是很严谨。
示例中给出了CoffeeShop表的几条样例数据,然后要求以样例数据的顺序来判断某条数据的上一条数据。
实际上,数据在数据库中存储时是无序的,如果不明确指定排序规则,SQL语句多次执行的顺序可能是不一样的。
如果需要明确的查出某条数据的前一条,必须先以一个明确的排序规则编出序号。显然根据题目描述,本题是没有一个明确的排序规则的。
当然,不是说没有明确的排序规则就无法排序,而是说下面同样的SQL,多次执行,可能排序结果不一样。
select     id,    drink,    row_number() over() rnfrom CoffeeShop;
抛开这个问题不谈,题目本身怎么解决呢?
假如,我们知道了每一行的排序序号,那么根据题目描述,如果当前行的drink为空,则需要返回上一个不为空的值。
也就是说,返回从当前行向前数,第一个drink的值不为空的行的drink值。
这里可以使用自关联来实现。
最后,再开窗排序,获取每行最近一个drink不为空的值即可。
参考SQL:
withtmp as (    select         id,        drink,        row_number() over() rn    from CoffeeShop)select    c.id,    c.drinkfrom (    select        a.id,        coalesce(a.drink,b.drink) drink,        a.rn,        row_number() over(partition by a.id order by b.rn desc) rn2    from tmp a    left join tmp b    on a.rn > b.rn    and b.drink is not null)cwhere c.rn2 = 1order by c.rn;
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论