[英]MySQL find date range with count
In MySQL, it is fairly easy to find the number of records that exist within some time interval. 在MySQL中,很容易找到某个时间间隔内存在的记录数。
SELECT COUNT(*) FROM records WHERE create_date > '2018-01-01 01:15:00' AND create_date < '2018-01-01 02:15:00'
But I want to do the opposite, sort of. 但是我想做相反的事情。 Rather than providing a time interval and getting a count of records, I want to provide a count of records and check if a X minute time interval exists where more than Y many records were created.
我不想提供时间间隔并获取记录计数,而是要提供记录计数并检查是否存在X分钟的时间间隔,其中创建的记录多于Y。 Getting the exact time interval is not essential, only if one exists or not.
只有存在或不存在时,获取精确的时间间隔不是必需的。 At a higher level, I am attempting to identify if there was any X minute "surge" when more than Y records where created during the course of a day.
在更高的级别上,我试图确定一天中创建的记录超过Y个记录时,是否存在X分钟的“波动”。
For example, in the past 24 hours was there any 1 hour interval where a "surge" of more than 50 new records occurred? 例如,在过去的24小时中,是否有1个小时的间隔发生了50多个新记录的“激增”?
I have already ruled out dividing the 24 hours into blocks of 1 hour intervals and checking each block. 我已经排除了将24小时划分为1小时间隔的块并检查每个块的可能性。 This does not work because the "surge" could span two sequential 1 hour blocks, such as 25 records at the end of the 01:00:00 block and 25 records at the beginning of the 02:00:00 block.
这不起作用,因为“喘振”可能跨越两个连续的1小时块,例如01:00:00块结束时有25条记录,而02:00:00块开始处有25条记录。
This should do it: 应该这样做:
SELECT COUNT(*)
FROM records r1
WHERE
(SELECT COUNT(*) FROM records r2
WHERE ABS(UNIX_TIMESTAMP(r1.create_date) - UNIX_TIMESTAMP(r2.create_date)) < X) > Y
What this does is count how many records have more than Y
records that have been created within X
seconds after or before each record. 这是计算在每条记录之后或之前
X
秒钟内创建的Y
记录多于Y
记录的数量。
So basically it will return >=1 if there are any, 0 if not. 所以基本上,如果有的话,它将返回> = 1,否则返回0。
So if you wanted to sort by hours you would want to group the records. 因此,如果您想按小时排序,则希望对记录进行分组。 Here I'm using the built-in functions that return parts of a timestamp,
year()
, month()
, dayofmonth()
, hour()
. 在这里,我使用的内置函数返回时间戳的一部分,
year()
, month()
, dayofmonth()
, hour()
。 Since you can't use an aggregate function in the where
clause I had to use having
to limit by the count requirement. 由于您不能在
where
子句中使用聚合函数,因此不得不使用having
受计数要求限制的函数。
select date(create_date),
hour(create_date),
count(*) as surge from records
where create_date > curdate() - interval 1 day
group by year(create_date), month(create_date),
dayofmonth(create_date), hour(create_date)
having count(*) > 50;
Another method to accomplish your goal might be to select
the count
of records and group by
the interval in question. 实现目标的另一种方法可能是
select
记录的count
,并按相关间隔进行group by
。 In this case I'm adding an hour to the create_date
to get your 1 hour suggested interval. 在这种情况下,我要向
create_date
添加一个小时,以获取建议的1小时间隔。 Anytime the count
is greater than 50 it returns a row. 每当
count
大于50时,它都会返回一行。 Notice I'm also grouping by
the hour
. 注意我也在
grouping by
hour
grouping by
。 This is to prevent multiple starts for a "surge" within the same hour: 这是为了防止在同一小时内多次启动“电涌”:
select create_date,count(*) as surge from records
group by year(create_date), month(create_date),
dayofmonth(create_date),hour(create_date),
(create_date + interval 1 hour - create_date) having count(*) > 50;
The problem with this however is that some surges may last longer than 1 hour, but it should give you the moment the "surge" started. 但是,这样做的问题是某些电涌可能会持续超过1个小时,但是应该让您立即开始“电涌”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.