MySQL:通过删除/聚合重复项和常量值来清理数据

MySQL:通过删除/聚合重复项和常量值来清理数据,mysql,aggregate,Mysql,Aggregate,在一个包含测量和状态数据的大型数据库中,我打算在不丢失大量信息的情况下减少数据。我研究了几个例子,但我的SQL技能似乎太有限,无法成功 该表包含数百万数据。表定义是 TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32) 一些示例数据。整个表格有许多不同的装置和读数,每个装置和读数

在一个包含测量和状态数据的大型数据库中,我打算在不丢失大量信息的情况下减少数据。我研究了几个例子,但我的SQL技能似乎太有限,无法成功

该表包含数百万数据。表定义是

TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32)
一些示例数据。整个表格有许多不同的装置和读数,每个装置和读数应单独处理:

+---------------------+----------+------+---------+---------+-------+------+
| TIMESTAMP           | DEVICE   | TYPE | EVENT   | READING | VALUE | UNIT |
+---------------------+----------+------+---------+---------+-------+------+
| 2016-03-27 10:17:45 | KNX_428c | KNX  |  49 mA  | state   | 49    | mA   |
| 2016-03-27 10:19:45 | KNX_428c | KNX  |  47 mA  | state   | 47    | mA   |
| 2016-03-27 10:21:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:23:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:23:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:25:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:25:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:27:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:27:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:29:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:31:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:31:44 | KNX_428c | KNX  |  47 mA  | state   | 47    | mA   |
| 2016-03-27 10:33:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:33:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:34:04 | KNX_428c | KNX  |  136 mA | state   | 136   | mA   |
| 2016-03-27 10:34:04 | KNX_428c | KNX  |  165 mA | state   | 165   | mA   |
| 2016-03-27 10:34:05 | KNX_428c | KNX  |  136 mA | state   | 136   | mA   |
| 2016-03-27 10:34:05 | KNX_428c | KNX  |  107 mA | state   | 107   | mA   |
| 2016-03-27 10:34:05 | KNX_428c | KNX  |  79 mA  | state   | 79    | mA   |
| 2016-03-27 10:34:06 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   |
| 2016-03-27 10:34:29 | KNX_428c | KNX  |  107 mA | state   | 107   | mA   |
| 2016-03-27 10:34:29 | KNX_428c | KNX  |  136 mA | state   | 136   | mA   |
| 2016-03-27 10:34:30 | KNX_428c | KNX  |  165 mA | state   | 165   | mA   |
| 2016-03-27 10:34:30 | KNX_428c | KNX  |  139 mA | state   | 139   | mA   |
| 2016-03-27 10:34:30 | KNX_428c | KNX  |  107 mA | state   | 107   | mA   |
| 2016-03-27 10:34:31 | KNX_428c | KNX  |  51 mA  | state   | 51    | mA   |
| 2016-03-27 10:34:44 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:35:44 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:37:44 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:37:44 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:39:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:41:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:43:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:45:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:47:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:47:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
| 2016-03-27 10:49:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |
我打算做两件事:

  • 使用max()聚合具有相同时间戳、设备和读取的值
  • 删除连续的相同值,除了常量值序列中的第一个和最后一个值
我在与group的select语句中实现的第一件事。但我不知道如何实际更改数据库

SELECT *,MAX(VALUE) FROM filelog
GROUP BY TIMESTAMP,DEVICE,READING
对于第二步,我找到了几个示例,但它们总是将重复项组合在一个记录中,而不是像我打算的那样组合在两个记录中(第一个和最后一个)。通常,这些示例使用JOIN,我认为这在数百万数据集上是不可能的

结果应如下所示:

| 2016-03-27 10:17:45 | KNX_428c | KNX  |  49 mA  | state   | 49    | mA   | 
| 2016-03-27 10:19:45 | KNX_428c | KNX  |  47 mA  | state   | 47    | mA   | 
| 2016-03-27 10:21:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   | 
| 2016-03-27 10:33:44 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   | 
| 2016-03-27 10:34:04 | KNX_428c | KNX  |  136 mA | state   | 165   | mA   | 
| 2016-03-27 10:34:05 | KNX_428c | KNX  |  136 mA | state   | 136   | mA   | 
| 2016-03-27 10:34:06 | KNX_428c | KNX  |  50 mA  | state   | 50    | mA   | 
| 2016-03-27 10:34:29 | KNX_428c | KNX  |  107 mA | state   | 136   | mA   | 
| 2016-03-27 10:34:30 | KNX_428c | KNX  |  165 mA | state   | 165   | mA   | 
| 2016-03-27 10:34:31 | KNX_428c | KNX  |  51 mA  | state   | 51    | mA   | 
| 2016-03-27 10:34:44 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   | 
| 2016-03-27 10:49:43 | KNX_428c | KNX  |  0 mA   | state   | 0     | mA   |   

感谢您的支持。

对于第一个查询,如果您想在聚合后获得完整记录,您需要做比您建议的更多的工作。一种方法是进行额外的连接:

SELECT t1.*
FROM filelog t1
INNER JOIN
(
    SELECT TIMESTAMP, DEVICE, READING, MAX(VALUE) AS VALUE
    FROM filelog
    GROUP BY TIMESTAMP, DEVICE, READING
) t2
    ON t1.TIMESTAMP = t2.TIMESTAMP AND
       t1.DEVICE    = t2.DEVICE    AND
       t1.READING   = t2.READING   AND
       t1.VALUE     = t2.VALUE

对于第一个查询,如果希望在聚合后获得完整记录,则需要做比建议的更多的工作。一种方法是进行额外的连接:

SELECT t1.*
FROM filelog t1
INNER JOIN
(
    SELECT TIMESTAMP, DEVICE, READING, MAX(VALUE) AS VALUE
    FROM filelog
    GROUP BY TIMESTAMP, DEVICE, READING
) t2
    ON t1.TIMESTAMP = t2.TIMESTAMP AND
       t1.DEVICE    = t2.DEVICE    AND
       t1.READING   = t2.READING   AND
       t1.VALUE     = t2.VALUE

我不清楚你的第二个要求。您能通过使用示例数据说明您的意思吗?记录的数量与联接操作无关。但我并不认为你真的需要一个。将要保留的记录复制到另一个表中并删除原始数据可能会更容易。第二步是否已完成并达到预期结果?我不清楚您的第二个要求。您能通过使用示例数据说明您的意思吗?记录的数量与联接操作无关。但我并不认为你真的需要一个。将要保留的记录复制到另一个表中并删除原始数据可能会更容易。第二步是否已完成并获得预期结果?很好,但有什么区别?我必须执行MAX(转换(值为十进制)为了获得2016-03-27 10:34:05的数据的正确最大值。但这不会改变文件日志中的数据本身,不是吗?进一步研究后,我意识到这个答案是错误的。它报告的记录没有重复。要求的是一个声明,从数据库中永久删除重复的报告,并用这是一个最大值的新记录。很好,但是有什么区别吗?我必须做MAX(CAST)(值为十进制)为了获得2016-03-27 10:34:05的数据的正确最大值。但这不会改变文件日志中的数据本身,不是吗?进一步研究后,我意识到这个答案是错误的。它报告的记录没有重复。要求的是一个声明,从数据库中永久删除重复的报告,并用使用最大值创建新记录。