SQL从日期范围中选择

时间:2015-11-06 21:28:25

标签: mysql date-range

我有一个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

感谢您的帮助!

2 个答案:

答案 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)

DEMO

答案 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);

Here's the SQL fiddle

相关问题