MySQL:从时间序列数据中提取计数器差异

时间:2012-06-28 10:39:35

标签: mysql series

我有一个像这样的MySQL表:

CREATE TABLE IF NOT EXISTS `mytable` (
  `ts` datetime NOT NULL,
  `cnt` int(10) unsigned NOT NULL,
  PRIMARY KEY (`ts`)
) ENGINE=InnoDB;

每当我们得到更新时,我们存储事件计数器的值;这些更新在任意时间到达。

我如何每X个时间段(例如5分钟,一天,一个月等)提取事件数量?我可以将其简化为通过日期/时间sql函数轻松提取的间隔(例如,小时,日,月等等)。

虽然我们没有任何保证,但与我想要提取的间隔相比,平均数据是“密集的”。例如。数据通常每小时出现多次,但我永远不会要求在一个区间内的事件数量< 1小时。如果存储的数据中存在“问题”(例如,大洞),则可以在结果中出现“问题”。

作为一个例子,我可以通过这样的查询得到我感兴趣的计数器值(24小时例子):

SELECT ts, cnt
FROM mytable
GROUP BY DATE( ts ) 
ORDER BY ts DESC

...并且可以通过用其前任减去每一行的计数器来轻松计算事件计数。但是如果可能的话,我想在SQL中做到这一点。

此外,如果这个问题有一个好名字(我认为当你使用时间序列和计数器时这是一个相当普遍的名字)我想知道它来提高我的词汇量:)

1 个答案:

答案 0 :(得分:3)

如果你要在你的桌子上添加一个AUTO_INCREMENT PRIMARY KEY,那将是可以解决的。

您提供的表架构无效(timestamp上的PRIMARY KEY,但没有此类列。)

你介意我们:

ALTER TABLE mytable DROP PRIMARY KEY, ADD COLUMN id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY

如果是这样,那么可以完成以下任务,我将分步介绍:

SELECT
  TIMESTAMPDIFF(SECOND, m1.ts, m2.ts) AS diff_seconds,
  m2.cnt - m1.cnt AS diff_cnt
FROM
  mytable m1 JOIN mytable m2 ON (m1.id = m2.id-1)
;

以上显示了连续样本之间的时间和cnt的差异。我们添加第三列:

SELECT
  TIMESTAMPDIFF(SECOND, m1.ts, m2.ts) AS diff_seconds,
  m2.cnt - m1.cnt AS diff_cnt,
  (m2.cnt - m1.cnt)/TIMESTAMPDIFF(SECOND, m1.ts, m2.ts) AS cnt_per_second
FROM
  mytable m1 JOIN mytable m2 ON (m1.id = m2.id-1)
;

我评估了cnt_per_second。乘以60得到每分钟cnt,依此类推。

现在,总平均值为:

SELECT 
  avg(cnt_per_second)
FROM (
  SELECT
    TIMESTAMPDIFF(SECOND, m1.ts, m2.ts) AS diff_seconds,
    m2.cnt - m1.cnt AS diff_cnt,
    (m2.cnt - m1.cnt)/TIMESTAMPDIFF(SECOND, m1.ts, m2.ts) AS cnt_per_second
  FROM
    mytable m1 JOIN mytable m2 ON (m1.id = m2.id-1)
) sel_diff
;

如果您想知道何时记录差异,则将原始n1.ts添加到第一个查询中,这样您也可以知道给定时间段内的平均计数事件。