简体   繁体   English

MySQL找到带有计数的日期范围

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM