【问题标题】:Replacing NULL value in current row based on 'closest' matching 'earlier' row. (date based table)根据匹配“较早”行的“最近”行替换当前行中的 NULL 值。 (基于日期的表格)
【发布时间】:2015-09-12 17:39:38
【问题描述】:

我有下面的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 |
+---------------------+------+

我想创建一个算法(在 PHP 中),根据最后一个非空值填充空值。所以表格会变成下面这样

+---------------------+------+
| 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 |
+---------------------+------+

我正在寻找有关如何处理这种情况的线索。我正在使用 PHP-Laravel。

这里有一个SQLFiddle 用于“标准”SQL。

【问题讨论】:

  • Drew 是对的,应该是关于插入函数的 SQL。但是,当您拥有的唯一工具是锤子时,所有问题都会变成钉子。
  • 显然他不喜欢我的评论并将其标记出来。射信使,没问题
  • @Drew 不,我没有,这让我对 Jamin 的评论感到困惑。能不能转发一下。
  • 我想那里有高级 PHP 爱好者,所以我会避免。我大量使用 PHP,我只是不为此目的使用它。一旦你得到你的答案,我会告诉你另一种方式,也许是鸽子消息传递
  • 但是@JaminQuimby,很多这些东西都是在数据修补之后

标签: php mysql laravel-5.1


【解决方案1】:

正如 cmets 所指出的,您应该在填充表格时解决此问题。也就是说,它可以在 PHP 或 MySQL 中完成。这是一种选择:

SET @x:=0;
SELECT `time`, IF(val IS NOT NULL, @x:=val, @x) AS val
FROM yourtable
ORDER BY `time`;

请记住,您的结果将根据订单和WHERE 等而改变。使用SET @x:=0; 为第一行具有NULL 值的情况定义默认值。

如果您需要永久修复数据,而不是针对单个查询,您可以使用“正确”值更新表:

SET @x:=0;
UPDATE yourtable SET val=IF(val IS NOT NULL, @x:=val, @x) 
 ORDER BY `time`;

【讨论】:

    【解决方案2】:

    如果你只想使用 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
    

    请看小提琴here

    对于每个 NULL 行,子查询将返回具有非 NULL 值的前一个日期。然后我将表与自身连接以获取值并更新空行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多