跳转至

2388. 将表中的空值更改为前一个值 🔒

题目描述

表: CoffeeShop

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| drink       | varchar |
+-------------+---------+
id 是该表的主键(具有唯一值的列)。
该表中的每一行都显示了订单 id 和所点饮料的名称。一些饮料行为 null。

 

编写一个解决方案将 drink 的 null 值替换为前面最近一行不为 null 的 drink。保证表第一行的 drink 不为 null

返回 与输入顺序相同的 结果表。

查询结果格式示例如下。

 

示例 1:

输入: 
CoffeeShop 表:
+----+-------------------+
| id | drink             |
+----+-------------------+
| 9  | Rum and Coke      |
| 6  | null              |
| 7  | null              |
| 3  | St Germain Spritz |
| 1  | Orange Margarita  |
| 2  | null              |
+----+-------------------+
输出: 
+----+-------------------+
| id | drink             |
+----+-------------------+
| 9  | Rum and Coke      |
| 6  | Rum and Coke      |
| 7  | Rum and Coke      |
| 3  | St Germain Spritz |
| 1  | Orange Margarita  |
| 2  | Orange Margarita  |
+----+-------------------+
解释: 
对于 ID 6,之前不为空的值来自 ID 9。我们将 null 替换为 "Rum and Coke"。
对于 ID 7,之前不为空的值来自 ID 9。我们将 null 替换为 "Rum and Coke"。
对于 ID 2,之前不为空的值来自 ID 1。我们将 null 替换为 "Orange Margarita"。
请注意,输出中的行与输入中的行相同。

解法

方法一:临时变量

我们可以使用一个临时变量 $cur$ 来记录上一个不为 $null$ 的值,如果当前值为 $null$,则将 $cur$ 的值赋给当前值,否则我们更新 $cur$ 的值为当前值。

1
2
3
4
5
6
7
8
# Write your MySQL query statement below
SELECT
    id,
    CASE
        WHEN drink IS NOT NULL THEN @cur := drink
        ELSE @cur
    END AS drink
FROM CoffeeShop;

方法二:窗口函数

我们先用窗口函数 row_number() 为每一行生成一个序号,然后使用 sum() 窗口函数来生成一个分组序号,分组序号的生成规则为:如果当前行的值为 $null$,则分组序号与上一行相同,否则分组序号加一。最后我们使用 max() 窗口函数来获取每一组唯一一个不为 $null$ 的值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Write your MySQL query statement below
WITH
    S AS (
        SELECT *, ROW_NUMBER() OVER () AS rk
        FROM CoffeeShop
    ),
    T AS (
        SELECT
            *,
            SUM(
                CASE
                    WHEN drink IS NULL THEN 0
                    ELSE 1
                END
            ) OVER (ORDER BY rk) AS gid
        FROM S
    )
SELECT
    id,
    MAX(drink) OVER (
        PARTITION BY gid
        ORDER BY rk
    ) AS drink
FROM T;

评论