我有一个RADIUS会话记录表,包括开始时间,停止时间和MAC地址。我需要收集两个时间段内在线用户的列表。我相信我通过以下查询在时间范围内获取所有在线用户的列表:
SELECT s_session_id, s_start_time, s_stop_time, s_calling_station_id
FROM sessions
WHERE (
("2015-10-01 08:00:00" BETWEEN s_start_time AND s_stop_time OR "2015-10-01 08:30:00" BETWEEN s_start_time AND s_stop_time)
OR
("2015-10-01 12:00:00" BETWEEN s_start_time AND s_stop_time OR "2015-10-01 12:30:00" BETWEEN s_start_time AND s_stop_time)
)
ORDER BY s_start_time;
但是,下一步,在两个期间仅在线隔离这些用户的详细信息,这是我的想法。我最接近的是添加
GROUP BY s_calling_station_id HAVING COUNT(s_calling_station_id) > 1
但这并没有向我提供所有会话详情。
小提琴在这里:http://sqlfiddle.com/#!9/1df471/1
感谢您的帮助!
答案 0 :(得分:2)
使用自我加入。使用列别名,以便您可以使用不同的名称访问每个会话中的列。
SELECT s1.s_calling_station_id,
s1.s_session_id AS s1_session_id, s1.s_start_time AS s1_start_time, s1.s_stop_time AS s1_stop_time,
s2.s_session_id AS s2_session_id, s2.s_start_time AS s2_start_time, s2.s_stop_time AS s2_stop_time
FROM sessions AS s1
JOIN sessions AS s2
ON s1.s_calling_station_id = s2.s_calling_station_id
AND s1.s_session_id != s2.s_session_id
WHERE ("2015-10-01 08:00:00" BETWEEN s1.s_start_time AND s1.s_stop_time OR "2015-10-01 08:30:00" BETWEEN s1.s_start_time AND s1.s_stop_time)
AND
("2015-10-01 12:00:00" BETWEEN s2.s_start_time AND s2.s_stop_time OR "2015-10-01 12:30:00" BETWEEN s2.s_start_time AND s2.s_stop_time)
答案 1 :(得分:1)
虽然这个问题已经有了一个可接受的答案,但我想添加这个问题(它避免了重复,并从满足条件的所有会话的会话表中提取数据):
首先,创建一个包含过滤数据的表(两个时间间隔都有连接的MAC地址:
create table temp_sessions
select s1.s_calling_station_id
, if(@t1_1 between s1.s_start_time and s1.s_stop_time or @t1_2 between s1.s_start_time and s1.s_stop_time, s1.s_session_id, null) as s_1
, if(@t2_1 between s2.s_start_time and s2.s_stop_time or @t2_2 between s2.s_start_time and s2.s_stop_time, s2.s_session_id, null) as s_2
from -- I use user variables because it will make easier to modify the time intervals if needed
(select @t1_1 := '2015-10-01 08:00:00', @t1_2 := '2015-10-01 08:30:00'
, @t2_1 := '2015-10-01 12:00:00', @t2_2 := '2015-10-01 12:30:00') as init
, sessions as s1
inner join sessions as s2
on s1.s_calling_station_id = s2.s_calling_station_id
and s1.s_session_id != s2.s_session_id
having s_1 is not null and s_2 is not null;
现在,只需使用此表即可获得所需内容:
select sessions.*
from sessions
inner join (
select s_calling_station_id, s_1 as s_session_id
from temp_sessions
union
select s_calling_station_id, s_2 as s_session_id
from temp_sessions
) as a using (s_calling_station_id, s_session_id);