我有一个带有日期时间行的MySQL表。如何在10分钟内找到至少包含5个条目的所有组?
我唯一的想法是编写一个程序(用任何语言)并循环遍历时间戳,检查总是5(..)个连续条目,计算最后一个和第一个之间的时间跨度,并检查它是否低于限制
这可以使用单个SQL查询来完成吗?
(场景简化,数字只是示例。)
根据要求,这里有一个例子:
id | timestamp | other_column
---|---------------------|-------------
3 | 2017-01-01 11:00:00 | thank
2 | 2017-01-01 11:01:00 | you
1 | 2017-01-01 11:02:00 | for
* 6 | 2017-01-01 11:20:00 | your
* 5 | 2017-01-01 11:21:00 | efforts
* 4 | 2017-01-01 11:22:00 | to
* 7 | 2017-01-01 11:23:00 | help
* 8 | 2017-01-01 11:24:00 | me
9 | 2017-01-01 11:40:00 | :
10 | 2017-01-01 11:41:00 | )
如果计数限制为5且时间跨度限制为10分钟,我希望获得标有“*”的条目。 “id”列是表的主键,但顺序并不总是时间戳的顺序。 “other_column”用于where子句。该表有大约100万个条目。
答案 0 :(得分:0)
尝试从逻辑上打破这一点。对不起psuedo代码位,我的时间有点短。
select t1.id, t1.timestamp, t2.timestamp
from yourtable t1
inner join yourtable t2 on t2.timestamp >= t1.timestamp and t2.timestamp < (t1.timestamp + 20 minutes)
(加上20分钟不能正常工作,使用适当的添加功能)
因此,这将为您提供一个相对较大的列表,列出在20分钟的时间间隔内加入任何其他ID的所有ID(包括自身的一行)。 (另外,我现在只挑选该组的第一行,更容易通过此时间戳加上20分钟抓住'标题行'并在下一步中担心其余部分)如果我们按ID和时间,我们得到20分钟内有多少行的计数:
select id, t1.timestamp, count(1)
from yourtable t1
inner join yourtable t2 on t2.timestamp >= t1.timestamp and t2.timestamp < (t1.timestamp + 20 minutes)
group by id, t1.timestamp
having count(1) > 4
现在,这将为您提供所有ID及其时间戳的列表,该时间戳自身以及距离该时间戳20分钟内的其他4条记录或更多记录。现在它取决于你想从这里分组的方式,如果你想要5行中的每一行,我们可以在子查询上面调用查询并将它连接回主表以获得你想要返回的行。
select t3.*
from
(select id, t1.timestamp, count(1)
from yourtable t1
inner join yourtable t2
on t2.timestamp >= t1.timestamp and t2.timestamp < (t1.timestamp + 20 minutes)
group by id, t1.timestamp
having count(1) > 4) a
inner join yourtable t3 on t3.timestamp >= a.timestamp and t3.timestamp < (a.timestamp + 20 minutes)
这应该给你身份证4-8并返回它的信息(按你认为合适的顺序)。
我很抱歉我没有时间去测试,但逻辑应该有用。