我有一个像这样的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中做到这一点。
此外,如果这个问题有一个好名字(我认为当你使用时间序列和计数器时这是一个相当普遍的名字)我想知道它来提高我的词汇量:)
答案 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添加到第一个查询中,这样您也可以知道给定时间段内的平均计数事件。