2015-11-06 102 views
-1

我有一個包含開始時間,停止時間和MAC地址的RADIUS會話記錄表。我有一個要求,收集兩個時間範圍內聯機的用戶列表。我相信,在與下面的查詢的時間範圍內,我讓所有用戶的列表在線:SQL從日期範圍中選擇

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

可我只是說,誰downvote提供一個明確的要求問題,示例代碼,鏈接,小提琴等不加評論的人是世界上最糟糕的人。嚴重的是,WTF在這個問題上是錯誤的? – miken32

+0

@Barranka不是針對你,只是對乙醚的呼喊! – miken32

+0

我不認爲它是個人的;)順便說一句,我覺得你的問題很有趣,我很高興你有一個很好的答案(我正在研究一個非常類似的方法,但巴爾馬速度更快)如果你希望看到我的方法,[這裏是SQL小提琴](http://sqlfiddle.com/#!9/1df471/39)。 – Barranka

回答

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

+0

謝謝,在我看來這是一個更好的解決方案,因爲它將每個會話放在自己的記錄上,不需要後處理。此外,它捕捉到某人只上線一次的情況,但會話重疊了兩個時間範圍。 – miken32

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

+0

不幸的是,這給出了與我的「GROUP BY」聲明(http://sqlfiddle.com/#!9/1df471/3)相同的結果。實際上我需要所有匹配會話的會話詳細信息。所以我應該看到會議4和5的細節。 – miken32

+0

你確實看到了兩個細節。會議4的詳細信息在左側,5的詳細信息在右側。 – Barmar

+0

啊,我明白了。不理想,但我可以與它合作。下一個問題,如果在時間範圍內有超過兩個匹配的會話,這個工作是否會起作用?看起來不像。 – miken32