按日期间隔大于 X 的 DATETIME 获取数据、计数和分组
Posted
技术标签:
【中文标题】按日期间隔大于 X 的 DATETIME 获取数据、计数和分组【英文标题】:Get data, count and group by DATETIME where date gap greater than X 【发布时间】:2018-08-13 14:29:46 【问题描述】:我有很多针对某个特定 API 的会话同时运行。 API 会不时更新,导致所有会话终止。
发生这种情况时,每个会话都会向我的中心网站报告错误“830”。
数据最终看起来像这样:
uid------error-------date
41 830 2018-05-14 13:45:13
42 830 2018-05-14 13:45:14
43 830 2018-05-14 13:45:16
44 830 2018-05-14 13:45:23
46 830 2018-05-14 13:46:19
50 830 2018-05-15 04:12:49
80 830 2018-05-15 04:12:49
36 830 2018-05-15 04:12:50
91 830 2018-05-15 04:15:52
12 830 2018-05-15 07:45:11
88 830 2018-05-15 07:45:11
92 830 2018-05-15 07:45:12
因为它随时可能发生,所以我需要能够通过下一位数据之间的间隙对这些数据进行分组。
例如,这是我想用上面的数据得到的输出并输出(其中间隙>10分钟):
update_date-----update_count
2018-05-14 1
2018-05-15 2
这是我迄今为止尝试过的:
select
count(eresult) as error_count,
CAST(added AS DATE) as error_date
from st__errors
where 1=1
and eresult = 20
group by date(added)
order by id desc
结果:
这对所有数据进行分组和计数,但不考虑间隔和按日期间隔分组,这是我遇到的问题。
我需要每天按每个错误日期之间的间隔对数据进行分组。我对自己的解释很糟糕,但希望这些例子能更好地描述我想要实现的目标?
【问题讨论】:
【参考方案1】:这将是一个非常慢的查询,但它是一个选项:
select count(e.eresult) as error_count,
CAST(e.added AS DATE) as error_date
from st__errors as e
where (
SELECT TIME_TO_SEC(TIMEDIFF(e.added, ei.added))
FROM st__errors as ei WHERE ei.id = e.id - 1
) > 10
and e.eresult = 20
group by date(e.added)
order by e.id desc
【讨论】:
谢谢你——我真的很努力解决这个问题,但是通过你的回答,我需要做的事情变得更加明显并且它有效!欣赏它:) 虽然这可能有效,但不建议依赖 id 是连续的或以正确的顺序。【参考方案2】:它并不漂亮,但我认为这可以通过 JOIN 来完成:
SELECT COUNT(*) grouped_error_count,
DATE(e1.added) error_date
FROM st__errors e1
/* Find other error within 10 mins */
LEFT JOIN st__errors e2
ON e2.added < e1.added
AND e2.added >= e1.added - INTERVAL 10 MINUTE
/* Find other error with exact same time (but only count one) */
LEFT JOIN st__errors e3
ON e3.added = e1.added
AND e3.id < e1.id
/* Has neither of the above */
WHERE e2.id IS NULL
AND e3.id IS NULL
GROUP BY error_date
ORDER BY error_date DESC;
我会远离使用id = id - 1
(或使用 id 进行排序),因为它依赖于连续的 id,即使使用 auto_increment,在手动插入完成或某些插入失败时也会出错。
我的查询仍应允许在添加的列上使用索引。
另外,如果这将成为一项功能而不仅仅是一次性查询,我会考虑将您的分组构建到录音中。这将使您的查询更快、更易读。
【讨论】:
我在这个表中有很多数据,它似乎需要很长时间才能运行 - 现在超过 5 分钟,我已经重新启动了我的数据库一次 你有added
的索引吗?
我会尽快回复您,我正在创建一个维护页面,这样我就可以在不杀死站点的情况下添加索引 x) 感谢您的帮助【参考方案3】:
这是一种更快的方法,但有时会将一组视为两组。
SELECT FLOOR(UNIX_TIMESTAMP(datetime) / (10*60)) AS ten_min_bucket,
COUNT(*) AS err_ct
FROM st__errors
GROUP BY ten_min_bucket;
一个变体可以让你看到时间范围:
SELECT MIN(datetime) AS err_start,
MAX(datetime) AS err_end,
COUNT(*) AS err_ct
FROM st__errors
GROUP BY FLOOR(UNIX_TIMESTAMP(datetime) / (10*60));
如果您在前一个结束后的几秒钟内看到一个错误簇,您将知道它们属于一起。一旦您习惯了这个“缺陷”,您可能希望将分辨率缩短到 5 分钟。
【讨论】:
以上是关于按日期间隔大于 X 的 DATETIME 获取数据、计数和分组的主要内容,如果未能解决你的问题,请参考以下文章