【问题标题】:MySQL query to group results by date range?MySQL查询按日期范围对结果进行分组?
【发布时间】:2013-09-20 20:32:29
【问题描述】:

当他连接应用程序时,我的系统每 2 到 5 秒 ping 一次数据库。根据他的连接,ping 时间范围可能会更长,比如 10 秒左右。

例子:

Pings: 1,4,6,8,9,12,16,20,50,180,187,189,200,203,206,210 ...

我想运行一个查询来获取 ping 之间不超过 1 分钟的范围,对它们进行分组,这样我就可以知道用户连接了多长时间,然后保存到一个新表中,例如:

Connections table:
user: X | start_date: 1   | end_date: 50  | duration: 49
user: X | start_date: 180 | end_date: 210 | duration: 30

由于来自 ,50,180, ... 的 ping 超过 1 分钟,查询组不予考虑。

ping 存储为时间戳,因此可以轻松转换为日期,从最后一个 ping 到第一个 ping 的范围将为我提供会话持续时间。

有没有办法在 MySQL 查询中执行此操作?有什么帮助吗?

编辑:添加 ping 历史架构

id  int(11)
user_id int(11)
ping_timestamp  int(11)

谢谢,

【问题讨论】:

  • 您能展示一下您的 ping 历史记录表是什么样的吗?
  • id int(11) | user_id int(11) | ping_timestamp int(11) ...

标签: mysql sql subquery


【解决方案1】:

我将您给定的示例数据翻了一番,以显示它如何与多个 userId 一起使用。

查看它在 sqlfiddle here 中的实时工作。

select
userid, groupnum,
min(ping) as start_date,
max(ping) as end_date,
max(ping) - min(ping) as duration
from (
select
*,
@groupnum := if(@prevUser != userId, @groupnum + 1, @groupnum),
@groupnum := if(ping - @prevTS > 60, @groupnum + 1, @groupnum) as groupnum,
@prevUser := userid,
@prevTS := ping
from
Table1 t
, (select @groupnum:=1, @prevTS:=NULL, @prevUser:=NULL) vars
order by userid, ping
) sq
group by userid, groupnum

【讨论】:

  • 如果数据按时间顺序插入表中是不行的,这是自然的情况sqlfiddle.com/#!2/c494a/2
  • @rsanchez 是的,小错误,已更正。随意删除downvote :) 并感谢您的提示。
  • 谢谢,完美运行。我将设置一个 cron 以每 10 分钟读取一次该表,并将所有过期的 pings 组(超过 60 秒)移动到一个新表中。所以我可以将 ping 表保留为内存类型,并且只将最终结果保存在第二个表上,您的查询如何打印它们。问题是我需要从该 ping 表中选择、插入和删除选定的结果。有可能吗?你能帮我如何进行吗?先谢谢了! @fancyPants
  • @Henrique 当然,但到目前为止我不明白问题出在哪里。你必须更详细地解释,听起来它更适合作为一个新问题。我去看看。
  • 我在这里重新发布了这个问题stackoverflow.com/questions/19061452/… ...感谢您的帮助@fancyPants
【解决方案2】:

在你的数据上试试这个:

set @rnum = 1;
select user_id
     , min(ping_timestamp) start_date
     , max(ping_timestamp) end_date
     , max(ping_timestamp)-min(ping_timestamp) duration
  from ( select user_id
              , ping_timestamp
              , @rnum := if(ping_timestamp - @prev_ping_ts > 60, @rnum+1, @rnum) rnum
              , @prev_ping_ts := ping_timestamp
           from test2
          order by user_id, ping_timestamp
       ) t
 group by user_id, rnum
;

【讨论】:

  • 你也应该初始化@prev_ping_ts
猜你喜欢
  • 2023-01-13
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 2019-02-14
  • 2013-04-05
  • 1970-01-01
  • 2018-07-09
相关资源
最近更新 更多