Mysql 计数包含给定值的开始和结束字段的记录

Mysql 计数包含给定值的开始和结束字段的记录,mysql,sql,Mysql,Sql,假设我有这样一个表(MySQL): CREATE TABLE sessions ( session_id INT NOT NULL AUTO_INCREMENT, name CHAR(12), start INT, end INT, PRIMARY KEY (session_id) ) 跟踪登录到应用程序的用户。每个用户登录都会在此表中创建一个条目,设置开始时间(作为从Unix历元开始计算秒数的整数),注销会以类似方式更新此表,设置结束时间。我的问题是在

假设我有这样一个表(MySQL):

CREATE TABLE sessions (
    session_id INT NOT NULL AUTO_INCREMENT,
    name CHAR(12),
    start INT,
    end INT,
    PRIMARY KEY (session_id)
)
跟踪登录到应用程序的用户。每个用户登录都会在此表中创建一个条目,设置开始时间(作为从Unix历元开始计算秒数的整数),注销会以类似方式更新此表,设置结束时间。我的问题是在一个时间范围内(通常是一天),每隔五分钟查找登录用户的数量

到目前为止,我所做的是编写一个在数据上循环的过程

SET t = begin_time;
WHILE t <= end_time DO
    SELECT t, COUNT(1) FROM TABLE WHERE start <= t AND end >= t;
    SET t = t + 300;
END WHILE;
SET t=开始时间;

虽然t我认为,您需要借助数字表,根据给定的时间范围和时间点之间的间隔,对每个时间点进行适当的分析

下面是一个可能的解决方案:

SET begin_time = ...
SET end_time = ...
SET interval_sec = 300;

CREATE TEMPORARY TABLE timestamps (unixtime int);
SET t = (begin_time + interval_sec - 1) div interval_sec;
WHILE t <= end_time DO
  INSERT INTO timestamps (unixtime) VALUES (t);
  SET t = t + interval_sec;
END WHILE;

SELECT
  t.unixtime,
  COUNT(s.session_id)
FROM timestamps t
  LEFT JOIN sessions s ON t.unixtime >= s.start AND t.unixtime < s.end;
GROUP BY t.unixtime
设置开始时间=。。。
设置结束时间=。。。
设置间隔_秒=300;
创建临时表时间戳(unixtime int);
设置t=(开始时间+间隔秒-1)div interval秒;
当t=s.start和t.unixtime
第三行根据时钟刻度确保所有被分析的时间戳都是5分钟间隔的开始。如果您希望它们以指定时间范围的开始为基础,请将其更改为简单的
SET t=begin\u time


此解决方案统计指定时刻的活动会话数。如果一个用户可能有多个并发会话,并且您想知道有多少不同的用户在线,那么您应该将
COUNT(s.session\u id)
替换为
COUNT(distinct s.name)

谢谢。我应该自己弄明白的:-)@ObiObi:起初我以为这会更棘手。部分原因是,最初我试图找到一种解决方案,对间隔内的会话/用户进行计数(误解了这个问题)。对于时间戳来说,这其实并不困难。此外,在我创建了一些索引之后,查询现在变得非常快速。我想比我原来的程序快一个数量级。
SET begin_time = ...
SET end_time = ...
SET interval_sec = 300;

CREATE TEMPORARY TABLE timestamps (unixtime int);
SET t = (begin_time + interval_sec - 1) div interval_sec;
WHILE t <= end_time DO
  INSERT INTO timestamps (unixtime) VALUES (t);
  SET t = t + interval_sec;
END WHILE;

SELECT
  t.unixtime,
  COUNT(s.session_id)
FROM timestamps t
  LEFT JOIN sessions s ON t.unixtime >= s.start AND t.unixtime < s.end;
GROUP BY t.unixtime