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)
虽然这个问题已经有一个可接受的答案,但我想添加这个(它避免重复并从满足条件的所有会话的会话 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);
我有一个 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)
虽然这个问题已经有一个可接受的答案,但我想添加这个(它避免重复并从满足条件的所有会话的会话 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);