SQL select 来自日期范围

SQL select from date ranges

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

但这并没有为我提供所有会话详细信息。

Fiddle 在这里:http://sqlfiddle.com/#!9/1df471/1

感谢您的帮助!

使用自联接。使用列别名,以便您可以访问每个会话中具有不同名称的列。

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

虽然这个问题已经有一个可接受的答案,但我想添加这个(它避免重复并从满足条件的所有会话的会话 table 中提取数据):

首先,创建一个 table 来保存过滤后的数据(在两个间隔上都有连接的 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;

现在,只需使用 table 即可获得您需要的东西:

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