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.
的行
我正在记录锅炉状态,意思是锅炉是否正在加热。我的 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.