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

时间:2015-03-10 12:03:39

标签: mysql optimization time-series

我记录锅炉状态,意味着锅炉是否加热。我的表看起来像这样:

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会读取锅炉状态代码并将其保存到表格中。数据如下所示:

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

是否可以撰写此活动?

谢谢!

1 个答案:

答案 0 :(得分:3)

这有点复杂,但您可以使用join中的delete来完成此操作。获得所需数据的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逻辑相反。在第一种情况下,您将获得要保留的行。第二个是删除的行。