MySQL 事件:删除时间序列数据而不做任何更改

MySQL event: Remove time-series data without change

我正在记录锅炉状态,意思是锅炉是否正在加热。我的 table 看起来像这样:

CREATE TABLE `boiler` (
  `tstamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `status_code` tinyint(3) unsigned NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

每 5 分钟 cron 读取锅炉状态代码并将其保存到 table。数据如下所示:

+---------------------+-------------+
| tstamp              | status_code |
+---------------------+-------------+
| 2015-02-16 01:30:02 |           0 |
| 2015-02-16 01:35:02 |           0 |
| 2015-02-16 01:40:02 |           1 |
| 2015-02-16 01:45:02 |           1 |
| 2015-02-16 01:50:02 |           1 |
| 2015-02-16 01:55:02 |           1 |
| 2015-02-16 02:00:02 |           1 |
| 2015-02-16 02:05:02 |           1 |
| 2015-02-16 02:10:02 |           1 |
| 2015-02-16 02:15:02 |           1 |
| 2015-02-16 02:20:02 |           0 |
| 2015-02-16 02:25:02 |           0 |
| 2015-02-16 02:30:02 |           0 |
| 2015-02-16 02:35:02 |           0 |
+---------------------+-------------+

现在,我想优化这些数据,也许是事件。我想原样删除数据,事件 运行 后,数据应如下所示:

+---------------------+-------------+
| tstamp              | status_code |
+---------------------+-------------+
| 2015-02-16 01:30:02 |           0 |
| 2015-02-16 01:40:02 |           1 |
| 2015-02-16 02:20:02 |           0 |
+---------------------+-------------+

这个活动可以写吗?

谢谢!

这个有点复杂,不过你可以在delete中加上一个join。一个获取你想要的数据的select没有那么复杂:

select b.*,
       (select b2.status_code
        from boiler b2
        where b2.tstamp < b.tstamp
        order by b2.tstamp desc
        limit 1
       ) as prev_status_code
from boiler b
having prev_status_code is null or prev_status_code <> status_code;

下一步就是把这个逻辑放到delete:

delete b
    from boiler b join
         (select b.*,
                 (select b2.status_code
                  from boiler b2
                  where b2.tstamp < b.tstamp
                  order by b2.tstamp desc
                  limit 1
                 ) as prev_status_code
         from boiler b
        ) b2
        on b.tstamp = b2.tstamp
    where b2.prev_status_code = b2.status_code;

where的逻辑是相反的。在第一种情况下,您会得到想要 保留 的行。第二个是要 delete.

的行