在新表中汇总数据

时间:2017-05-09 09:39:49

标签: mysql

问题如下,当天数据被放入status_table(每天最多可达4000个条目

在夜间,我想以更有条理的方式将数据放入存储表中 (status_table_storage)并将其从status_table中删除。 我们的想法是将所有具有相同状态的条目分组,直到状态/错误发生变化。从那时起,一个新组应该开始被放入表中。一个例子可以在小提琴中找到

最好的方法是什么。

可以在此处找到表结构的示例:http://sqlfiddle.com/#!9/488524/1

1 个答案:

答案 0 :(得分:2)

分步说明:

首先按名称和时间戳订购表格并初始化三个user-defined variables

SELECT s.* FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

如您所见,我们可以使用子查询。 ORDER BY很重要,因为除非您指定它,否则关系数据库中没有顺序。

现在,MySQL以指定的顺序评估SELECT子句,因此不要在此处更改顺序。

SELECT 
s.*,
@prevName,
@prevStatus,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

当你执行这个语句时,你可以看到,当我们只选择变量时,它们保存前一行的值,或者当它是第一行时读取的是NULL。然后将当前行的值分配给变量。所以我们现在可以将当前行与前一行进行比较。如果发生了变化,我们只需增加第三个变量,这是我们正在构建的每个“组”的数字。

SELECT 
s.*,
@group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
@prevName := s.name,
@prevStatus := s.status
FROM status_table s
, (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
ORDER BY name, timestamp

因此,当某些内容发生变化时,我们会增加@group_number,如果没有,则将变量分配给自身,以便它不会发生变化。

现在我们可以简单地将此查询用作子查询并进行简单分组。

SELECT 
group_number AS id, 
name, 
status, 
MIN(error) AS error, 
MIN(timestamp) AS firstEntry,
MAX(timestamp) AS lastEntry,
COUNT(*) AS entries
FROM (
    SELECT 
    s.*,
    @group_number := IF(@prevName != s.name OR @prevStatus != s.status, @group_number + 1, @group_number) AS group_number,
    @prevName := s.name,
    @prevStatus := s.status
    FROM status_table s
    , (SELECT @group_number := 0, @prevName := NULL, @prevStatus := NULL) var_init_subquery
    ORDER BY name, timestamp
) sq
GROUP BY 
group_number, 
name, 
status