表:CoffeeShop
Column Name | Type |
---|---|
id | int |
drink | varchar |
编写一个解决方案将 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”。
请注意,输出中的行与输入中的行相同。
思路:首先要求里面的输出顺序还是和原先一样,原先并没有按什么排序,所以我们得先对数据标上序号,这就可以用到窗口函数 row_numer,然后我们只需要在查询到 null 数据的时候,去查询比这个 null 数据的序号小的不为 null 的数据,然后根据序号倒序,取第一条即可,就能满足要求
里面需要注意的一点就是窗口函数 ROW_NUMBER() over()
,over
括号里面是不加分组和排序的
WITH tmp AS (
SELECT *, ROW_NUMBER() over() AS rn
FROM CoffeeShop
)
SELECT id,
IFNULL(
drink,
(SELECT drink FROM tmp WHERE rn < one.rn AND drink IS NOT NULL ORDER BY rn DESC LIMIT 1)
) AS drink
FROM tmp AS one
临时变量有两种用法:(temp 可以改成其他名)
1、使用 set,定义形式 set @temp=[var]
SET @temp=10;
SELECT @temp;
2、使用 select,定义形式 select @temp:=[var],下面两种都可以输出
SELECT @temp:=10;
SELECT @temp:=10;
SELECT @temp;
参考:mysql 临时变量
SELECT id,
@temp := IFNULL(drink, @temp) drink
FROM CoffeeShop
上面网友写法就是用的第二种用法,代码分析如下:
第 1 行:IFNULL
不为 null
,将 Rum and Coke
赋值到 @temp
里面,并输出 SELECT @temp:= drink
(drink='Rum and Coke'
)
第 2 行:IFNULL
为 null
,将 @temp
赋值到 @temp
里面,并输出 SELECT @temp:=@temp
(@temp='Rum and Coke'
)
第 3 行:IFNULL
为 null
,将 @temp
赋值到 @temp
里面,并输出 SELECT @temp:=@temp
(@temp='Rum and Coke'
)
第 4 行:IFNULL
不为 null
,将 St Germain Spritz
赋值到 @temp
里面,并输出 SELECT @temp:= drink
(drink='St Germain Spritz'
)
第 5 行:IFNULL
不为 null
,将 Orange Margarita
赋值到 @temp
里面,并输出 SELECT @temp:= drink
(drink='Orange Margarita'
)
第 6 行:IFNULL
为 null
,将 @temp
赋值到 @temp
里面,并输出 SELECT @temp:=@temp
(@temp='Orange Margarita'
)
id | drink |
---|---|
9 | Rum and Coke -> @temp |
6 | null <- @temp |
7 | null <- @temp |
3 | St Germain Spritz -> @temp |
1 | Orange Margarita -> @temp |
2 | null <- @temp |