MySQL查询GROUP BY和COUNT基于输入间隔+考虑两个表colums作为间隔

时间:2010-11-06 17:42:53

标签: mysql

我正在编写一个查询,该查询将从日志记录表中获取结果,从而可以概述在指定的时间间隔内在我的网页上记录的访问者数量,并考虑到他们的实际登录时间(login_time,logout_time)和输入GROUP by参数。 (DAY(),HOUR()或MINUTE())

我已经把我的大脑扭曲了几天。真的需要任何感兴趣的人的积极投入。

输入

基本上我在查询中输入的内容是我想要搜索的时间间隔。指定结果如何分组。 (DAY(),HOUR()或MINUTE())

示例数据

ID| userID | login_time          | logout_time
------------------------------------------------------
1 | 1      | 06.11.2010 16:57:16 | 06.11.2010 16:34:11
2 | 2      | 06.11.2010 16:47:11 | 06.11.2010 19:55:15
3 | 3      | 06.11.2010 16:33:16 | 06.11.2010 16:53:33
4 | 4      | 06.11.2010 16:13:25 | 06.11.2010 18:54:54
5 | 5      | 06.11.2010 16:02:16 | 06.11.2010 16:34:11
6 | 6      | 06.11.2010 16:00:11 | 06.11.2010 17:55:19
7 | 6      | 06.11.2010 19:00:11 | 06.11.2010 22:55:19
8 | 6      | 06.11.2010 20:00:11 | 06.11.2010 23:55:19
9 | 6      | 06.11.2010 20:00:11 | 06.11.2010 21:55:19
9 | 6      | 06.11.2010 09:00:11 | 06.11.2010 10:00:19

首选结果

示例输入:2010年11月6日 16:30:00 和06.11.2010 16:35:00 之间,并按MINUTE()分组

Count | Date
---------------------------
5     | 06.11.2010 16:30:00
5     | 06.11.2010 16:31:00
5     | 06.11.2010 16:32:00
4     | 06.11.2010 16:33:00
5     | 06.11.2010 16:34:00
3     | 06.11.2010 16:35:00

示例输入:2010年11月6日 00:30:00 和06.11.2010 23:35:00 之间,按小时()分组

Count | Date
---------------------------
1     | 06.11.2010 09:00:00
1     | 06.11.2010 10:00:00

- > PS:如果缺少间隔(即没有数据),我不介意在这里有差距

6     | 06.11.2010 16:00:00
3     | 06.11.2010 17:00:00
2     | 06.11.2010 18:00:00
2     | 06.11.2010 19:00:00
3     | 06.11.2010 20:00:00
3     | 06.11.2010 21:00:00
2     | 06.11.2010 22:00:00
1     | 06.11.2010 23:00:00

也许你可以说明一个合适而有效的查询,它会产生我想到的预期结果?我暂时将这个杂乱的代码留在这篇文章中。

2 个答案:

答案 0 :(得分:3)

抱歉,没有办法使用单个查询。因为SQL基于集合论,所以你必须创建一组时间间隔。

您可以在临时表或存储过程中执行此操作,计算时间间隔并对每个间隔执行查询。

所以你可以这样做:

CREATE TEMPORARY TABLE temp_intervals (
    start_datetime DATETIME NOT NULL ,
    end_datetime DATETIME NOT NULL
)

INSERT INTO temp_intervals(start_datetime, end_datetime) VALUES
    ('2010-11-06 16:30:00', '2010-11-06 16:31:00'),
    ('2010-11-06 16:31:00', '2010-11-06 16:32:00')
    ...

然后执行查询:

SELECT start_datetime, COUNT(*)
FROM temp_intervals
LEFT JOIN login_history -- LEFT JOIN if you want empty intervals in the result
WHERE login_time <= start_datetime AND logout_time > end_datetime
GROUP BY start_datetime

请记住,所有语句都必须在一个连接中完成,因为临时表只对该连接可见。

此外,您不需要任何过程语言,因为您可以让MySQL使用存储过程创建临时表。

答案 1 :(得分:2)

在SQL中执行此操作的最简单方法是创建一个包含要测试的所有时间值的临时表,然后将其加入日志表。

drop table if exists minutes;
create temporary table minutes (date datetime not null);
set @t := '2010.11.06 16:30:00';  insert into minutes values (@t);
set @t := @t + interval 1 minute; insert into minutes values (@t);
set @t := @t + interval 1 minute; insert into minutes values (@t);
set @t := @t + interval 1 minute; insert into minutes values (@t);
set @t := @t + interval 1 minute; insert into minutes values (@t);
set @t := @t + interval 1 minute; insert into minutes values (@t);

select count(*) as count, m.date
from minutes m join log l
on m.date <= l.logout_time and m.date + interval 1 minute >= l.login_time
group by m.date;