简体   繁体   English

根据“最接近”匹配的“早期”行替换当前行中的NULL值。 (基于日期的表格)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM