如何在 MySQL 中将 IFNULL 与 window 函数一起使用

How do I use IFNULL with window function in MySQL

如何将 ifnull 与 window 函数一起使用?

假设我有下面这个查询结果,lag1 只是使用 window 函数向下移动的预算列,因此,该值为空。但我想用零替换该空值,以便计算预算和滞后 1 之间的差异。

select id, budget,
    lag(budget) over (order by id) as lag1
    from projects;

+----+---------+---------+
| id | budget  | lag1    |
+----+---------+---------+    
|  1 | 1000000 |    NULL |  
|  2 |  100000 | 1000000 |  
|  3 |     100 |  100000 |
+----+---------+---------+

我尝试了以下两个示例,但它不起作用:

select id, budget,
ifnull(lag(budget),0) over (order by id) as lag1
from projects;

select id, budget,
ifnull((lag(budget) over (order by id) as lag1),0)
from projects;

我猜你的 mysql 版本低于 8.0,因为你的第二个解决方案已经成功了。

select id, budget, ifnull(lag(budget) over (order by id),0) as lag1
from projects;

sqlfiddle

如果你的mysql版本低于8.0,你需要在select中写一个子查询,通过ID

获取行前数据

TESTDDL

CREATE TABLE projects(
  ID INT,
   budget INT
);
INSERT INTO projects VALUES (1,1000000);
INSERT INTO projects VALUES (2,100000);
INSERT INTO projects VALUES (3,100);

查询

SELECT *,IFNULL((select budget FROM projects t1 WHERE t.id > t1.id order by t1.id desc limit 1 ) ,0) lag1
FROM projects t

[结果]:

| ID |  budget |    lag1 |
|----|---------|---------|
|  1 | 1000000 |       0 |
|  2 |  100000 | 1000000 |
|  3 |     100 |  100000 |

sqlfiddle

lag() 最多接受三个参数。第一个是返回值的表达式。这里只是列名。第二个确定它应该在后面查看多少行。默认为一个。第三个,对你来说很有趣,是一个默认值,如果没有找到前一行的话。

因此您可以直接在 lag() 调用中定义默认值:

SELECT id,
       budget,
       lag(budget, 1, 0) OVER (ORDER BY id) lag1
       FROM projects;