【问题标题】:MySQL search for concurrent time stamps over an allowed limit, then tally the SUM?MySQL 搜索超过允许限制的并发时间戳,然后计算 SUM?
【发布时间】:2013-12-13 19:22:28
【问题描述】:

数周以来,我一直在绞尽脑汁思考如何正确实现这一目标,一直在玩 PHP 和 mySQL,但我编写的每个公式或函数似乎都缺少一些东西。这正是我想要做的..

-填充登录记录的mySQL数据库。

-字段为 RECORD、START_TIME、DURATION、CUSTOMERID

-RECORD 是唯一键

-START_TIME 是“2013-12-12 10:32:59”类型格式

-DURATION 以秒为单位

-CUSTOMERID是用户的唯一账号

每个用户可以同时登录 3 次,任何一次超过 3 次的登录我都需要在“超额”期间为该用户计算所有会话的总 DURATION 秒数。

所以一个例子是..

RECORD  |  START_TIME        |  DURATION  |  CUSTOMERID
   1       2013-1-1 12:00:00      10          BILLYBOB
   2       2013-1-1 12:01:00      600         BILLYBOB
   3       2013-1-1 12:04:00      1200        BILLYBOB
   4       2013-1-1 12:05:20      500         BILLYBOB
   5       2013-1-1 12:06:30      600         BILLYBOB
   6       2013-1-1 16:00:00      100         BILLYBOB
   7       2013-1-1 18:00:00      300         BILLYBOB

在这种情况下,它会返回记录 2、3、4、5,因为有超过 3 个同时会话,然后返回这些记录的总持续时间,即 2900。

这是否对 MySQL 要求过高?

【问题讨论】:

  • 这很可能是一个非常难以理解和复杂的 SQL 查询。我的建议是在旨在处理逻辑的东西中创建它。比如编程语言;)
  • 'overage' wassat? @user202172 '红布对公牛' ;-)
  • 我正在使用 PHP,但我认为我的查询与查询中的查询的想法可能需要 10 个小时才能运行一个实例,哈哈
  • 我会在检查登录时亲自添加此逻辑,而不是尝试对值进行后处理。例如,当尝试登录时,您可以检测当前登录的次数。
  • 这当然是一个很好的难题。只是为什么,在找到重叠的记录后,你想要总结它们的持续时间让我无法理解。

标签: php mysql sql


【解决方案1】:

好的,我知道了……

首先,您必须找到每个用户的时间片。假设他/她从 10:00:00 到 10:09:59 以及从 10:10:00 到 10:19:59 以及从 10:00:00 到 10:29:59 工作。这为您提供了三个时间片:10:00:00 到 10:09:59(会话 1 和 3)、10:10:00 到 10:19:59(会话 2 和 3)和 10:20:00 到 10 :29:59(第 3 节)。

然后您计算每个时间片中活动的会话,并删除时间片只有三个或更少的会话处于活动状态。找到那些违反的时间片后,您可以选择当时处于活动状态的会话。

这是完整的声明:

select *
from sessions
where exists
(
  select *
  from
  (
    select start_times.customerid, start_times.start_time, min(end_times.end_time) as end_time
    from
    (
      select customerid, start_time from sessions
      union
      select customerid, date_add(start_time, interval duration second) from sessions
    ) start_times
    join
    (
      select customerid, date_add(start_time, interval duration - 1 second) as end_time from sessions
      union
      select customerid, date_add(start_time, interval -1 second) from sessions
    ) end_times
    on (start_times.customerid = end_times.customerid and start_times.start_time < end_times.end_time)
    group by start_times.customerid, start_times.start_time
  ) time_slices
  where 
  (
    select count(*) 
    from sessions
    where time_slices.customerid = sessions.customerid
    and
    (
      time_slices.start_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second)
      and
      time_slices.end_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second)
    )
  ) > 3
  and time_slices.customerid = sessions.customerid
  and
  (
    time_slices.start_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second)
    and
    time_slices.end_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second)
  )
)
;

这里是 SQL 小提琴:http://sqlfiddle.com/#!2/12c47/1

【讨论】:

  • @Matthew Malkowski:这有帮助吗?
【解决方案2】:

这里是一个应该可以解决问题的查询:

SELECT
    record, `start_time`, date_add(`start_time`, interval `duration` second) as end_time, `customerid`,
    `duration`+(select sum(`duration`)
        from `testtbl` as b
        where b.record > a.record and b.customerid=a.customerid and b.start_time <= end_time
        having count(*) >= 3
    ) as sumduration
FROM
`testtbl` as a
having sumduration is not null

这个查询不是很快,但基于它你可以反规范化你的数据库并获得更快的版本

注意:如果我们有这样的数据,我们可能会遇到问题:

1 2013-1-1 12:00:00 60 BILLYBOB
2 2013-1-1 12:00:10 60 BILLYBOB
3 2013-1-1 12:00:20 60 BILLYBOB
4 2013-1-1 12:00:30 60 BILLYBOB
5 2013-1-1 12:01:09 60 BILLYBOB

record 1 is overlapped only with 2,3,4 NOT with 5
record 2 is overlapped only with 3,4,5

这实际上不是一个错误,因为我们有 4 次登录,然后 1 次在 1:00 注销,然后再次第 4 次登录到系统

两条记录都将通过查询显示,具体取决于您对结果的处理方式,您可以以不同的方式处理这种情况

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多