的问题是日数据中如下放入status_table(这可高达每天汇总数据
4000项期间,我希望把数据放到一个更有条理的夜晚在存储表 (status_table_storage)中,并将其从status_table中删除 这个想法是将所有状态相同的条目分组,直到状态/错误发生变化为止,新组应该开始被放入表可以在小提琴中找到一个例子
做这件事的最好方法是什么
表结构的一个例子可以在这里找到:http://sqlfiddle.com/#!9/488524/1
的问题是日数据中如下放入status_table(这可高达每天汇总数据
4000项期间,我希望把数据放到一个更有条理的夜晚在存储表 (status_table_storage)中,并将其从status_table中删除 这个想法是将所有状态相同的条目分组,直到状态/错误发生变化为止,新组应该开始被放入表可以在小提琴中找到一个例子
做这件事的最好方法是什么
表结构的一个例子可以在这里找到:http://sqlfiddle.com/#!9/488524/1
一步一步的解释:
首先,你的名字和时间戳订购表,并初始化3 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
感谢您的很好的解释 –
不客气工作。 – fancyPants