[英]Replacing NULL value in current row based on 'closest' matching 'earlier' row. (date based table)
I have the following mysql table 我有以下mysql表
+---------------------+------+
| time | val |
+---------------------+------+
| 2005-02-03 00:00:00 | 2.11 |
| 2005-02-04 00:00:00 | 2.11 |
| 2005-02-05 00:00:00 | NULL |
| 2005-02-06 00:00:00 | NULL |
| 2005-02-07 00:00:00 | 3.43 |
| 2005-02-08 00:00:00 | NULL |
| 2005-02-09 00:00:00 | NULL |
| 2005-02-10 00:00:00 | 5.66 |
| 2005-02-11 00:00:00 | 5.66 |
| 2005-02-12 00:00:00 | NULL |
+---------------------+------+
I want to create an algorithm (in PHP) that fill the NULL values based on the last non-null value. 我想创建一个算法(在PHP中),根据最后一个非空值填充NULL值。 So the table will become the following
因此该表将成为以下内容
+---------------------+------+
| time | val |
+---------------------+------+
| 2005-02-03 00:00:00 | 2.11 |
| 2005-02-04 00:00:00 | 2.11 |
| 2005-02-05 00:00:00 |>2.11 |
| 2005-02-06 00:00:00 |>2.11 |
| 2005-02-07 00:00:00 | 3.43 |
| 2005-02-08 00:00:00 |>3.43 |
| 2005-02-09 00:00:00 |>3.43 |
| 2005-02-10 00:00:00 | 5.66 |
| 2005-02-11 00:00:00 | 5.66 |
| 2005-02-12 00:00:00 |>5.66 |
+---------------------+------+
I'm looking for clues on how to approach this situation. 我正在寻找如何处理这种情况的线索。 I'm using PHP-Laravel.
我正在使用PHP-Laravel。
There is an SQLFiddle here for 'standard' SQL. 这里有一个SQLFiddle用于'标准'SQL。
As comments indicate, you should be fixing this when you populate the table. 正如评论所示,您应该在填充表时修复此问题。 That said, it can be done in PHP or MySQL.
也就是说,它可以在PHP或MySQL中完成。 Here is one option:
这是一个选项:
SET @x:=0;
SELECT `time`, IF(val IS NOT NULL, @x:=val, @x) AS val
FROM yourtable
ORDER BY `time`;
Bear in mind that your result will change depending on ordering and WHERE
and so on. 请记住,您的结果将根据订购和
WHERE
而改变。 Use SET @x:=0;
使用
SET @x:=0;
to define your default value for cases when first row has NULL
value. 为第一行具有
NULL
值的情况定义默认值。
If you need to fix the data permanently, rather than for single query, you can update the table with 'correct' values: 如果您需要永久修复数据,而不是单个查询,则可以使用“正确”值更新表:
SET @x:=0;
UPDATE yourtable SET val=IF(val IS NOT NULL, @x:=val, @x)
ORDER BY `time`;
If you want to use just SQL, you could use this UPDATE query: 如果您只想使用SQL,则可以使用此UPDATE查询:
UPDATE
tab INNER JOIN (
SELECT
t1.time,
MAX(t2.time) prev_time
FROM
tab t1 INNER JOIN tab t2
ON t1.time>t2.time
WHERE
t1.val IS NULL
AND t2.val IS NOT NULL
GROUP BY
t1.time
) p ON tab.time = p.time
INNER JOIN tab t2 ON p.prev_time = t2.time
SET
tab.val = t2.val
Please see a fiddle here . 请在这里看一个小提琴。
The subquery will return, for every NULL row the previous date with a non-NULL value. 对于每个NULL行,子查询将返回具有非NULL值的上一个日期。 Then I'm joining the table with itself to get the value and to update the null row.
然后我自己加入表来获取值并更新空行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.