2013-12-12 30 views
2

在我如何正確實現這個目標的過程中,我的腦子一直在被困住,一直在用PHP編寫PHP & mySQL,但我寫的每一個公式或函數似乎都缺少一些東西。這正是我想要做的。MySQL搜索超過允許限制的併發時間戳,然後計算SUM?

-mySQL數據庫充滿了登錄記錄。

-Fields是RECORD,START_TIME,持續時間,CUSTOMERID

-record是唯一鍵

-start_time處於 「2013年12月12日10點32分59秒」 類型格式

-DURATION是以秒

-CUSTOMERID是

允許每個用戶3所同時登錄的用戶的唯一帳號,上述3中的任登錄在我需要在「超額」期間爲所有會話的用戶計算DURATION的總時間。

因此,一個例子是..

RECORD | START_TIME  | DURATION | CUSTOMERID 
    1  2013-1-1 12:00:00  10   BILLYBOB 
    2  2013-1-1 12:01:00  600   BILLYBOB 
    3  2013-1-1 12:04:00  1200  BILLYBOB 
    4  2013-1-1 12:05:20  500   BILLYBOB 
    5  2013-1-1 12:06:30  600   BILLYBOB 
    6  2013-1-1 16:00:00  100   BILLYBOB 
    7  2013-1-1 18:00:00  300   BILLYBOB 

在這種情況下,它會返回記錄2,3,4,5因爲有超過3個併發會話,然後返回這些記錄的總持續時間將是2900.

這是否要求太多的MySQL?

+1

這是非常可能的一個真正難以理解和複雜的SQL查詢。我的建議是在一些旨在處理邏輯的東西中創建它。如編程語言;) – user202172

+0

'超額'wassat? @ user202172'紅牛抹布';-) – Strawberry

+0

我在玩PHP,但我想我的想法查詢內查詢可能需要10個小時才能運行一個實例lol –

回答

1

好,我知道現在......

首先,你必須找到時間每個用戶片。說他們從10:00:00到10:09:59以及從10:10:00到10:19:59和從10:00:00到10:29:59工作。這給你三個時間片:10:00:00至10:09:59(會議1和3),10:10:00至10:19:59(會議2和3)和10:20:00至10 :29:59(第三場)。

然後,您計算在每個時間片中處於活動狀態的會話,並刪除只有三個或更少的會話處於活動狀態的切片。在發現違反時間片的情況下,您可以選擇當時處於活動狀態的會話。

下面是完整的語句:

select * 
from sessions 
where exists 
(
    select * 
    from 
    (
    select start_times.customerid, start_times.start_time, min(end_times.end_time) as end_time 
    from 
    (
     select customerid, start_time from sessions 
     union 
     select customerid, date_add(start_time, interval duration second) from sessions 
    ) start_times 
    join 
    (
     select customerid, date_add(start_time, interval duration - 1 second) as end_time from sessions 
     union 
     select customerid, date_add(start_time, interval -1 second) from sessions 
    ) end_times 
    on (start_times.customerid = end_times.customerid and start_times.start_time < end_times.end_time) 
    group by start_times.customerid, start_times.start_time 
) time_slices 
    where 
    (
    select count(*) 
    from sessions 
    where time_slices.customerid = sessions.customerid 
    and 
    (
     time_slices.start_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second) 
     and 
     time_slices.end_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second) 
    ) 
) > 3 
    and time_slices.customerid = sessions.customerid 
    and 
    (
    time_slices.start_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second) 
    and 
    time_slices.end_time between sessions.start_time and date_add(sessions.start_time, interval duration - 1 second) 
) 
) 
; 

這裏是SQL小提琴:http://sqlfiddle.com/#!2/12c47/1

+0

@馬修馬爾科夫斯基:這有幫助嗎? –

0

這裏是查詢應該做的伎倆:

SELECT 
    record, `start_time`, date_add(`start_time`, interval `duration` second) as end_time, `customerid`, 
    `duration`+(select sum(`duration`) 
     from `testtbl` as b 
     where b.record > a.record and b.customerid=a.customerid and b.start_time <= end_time 
     having count(*) >= 3 
    ) as sumduration 
FROM 
`testtbl` as a 
having sumduration is not null 

這個查詢是不是非常快,但是基於它,你可以去正常化你分貝,並獲得更快的版本

注意:我們可以有問題,如果我們有這樣的數據:

1 2013-1-1 12:00:00 60 BILLYBOB 
2 2013-1-1 12:00:10 60 BILLYBOB 
3 2013-1-1 12:00:20 60 BILLYBOB 
4 2013-1-1 12:00:30 60 BILLYBOB 
5 2013-1-1 12:01:09 60 BILLYBOB 

record 1 is overlapped only with 2,3,4 NOT with 5 
record 2 is overlapped only with 3,4,5 

這實際上不是一個錯誤,因爲我們4個登錄,然後在1 1:00註銷,然後重新登錄4日到系統

兩個記錄將被查詢顯示,這取決於你將與結果做什麼,你可以處理這種情況的不同