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

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

跟强哥学SQL 2023-01-09
197
题目: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() rn
        from CoffeeShop;
        抛开这个问题不谈,题目本身怎么解决呢?
        假如,我们知道了每一行的排序序号,那么根据题目描述,如果当前行的drink为空,则需要返回上一个不为空的值。
        也就是说,返回从当前行向前数,第一个drink的值不为空的行的drink值。
        这里可以使用自关联来实现。
        最后,再开窗排序,获取每行最近一个drink不为空的值即可。
        参考SQL:
          with
          tmp as (
          select
          id,
          drink,
          row_number() over() rn
          from CoffeeShop
          )
          select
          c.id,
          c.drink
          from (
          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
          )c
          where c.rn2 = 1
          order by c.rn;

          单挑力扣(LeetCode)SQL笔试题:2324. 产品销售分析 IV(难度:中等)
          单挑力扣(LeetCode)SQL笔试题:2346. 以百分比计算排名(难度:中等)
          单挑力扣(LeetCode)SQL笔试题:2372. 计算每个销售人员的影响力(难度:中等)

          文章转载自跟强哥学SQL,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论