Been racking my brain for weeks on how I could correctly achieve this, been playing around with PHP & mySQL but every formula or function I write seems to be missing something. Here's exactly what I'm trying to do..
-mySQL database filled with records of logins.
-Fields are RECORD,START_TIME,DURATION,CUSTOMERID
-RECORD is unique key
-START_TIME is in the "2013-12-12 10:32:59" type format
-DURATION is in seconds
-CUSTOMERID is the unique account number of user
Each user is allowed 3 simultaneous logins, any logins above 3 at a time I need to tally up a total of seconds of DURATION for that user of all sessions during the "overage".
So an example would be..
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
In this case, it would return records 2,3,4,5 since there was over 3 simultaneous sessions, then return the total duration of those records which would be 2900.
Is this asking too much of MySQL?
Okay, I got it now...
First you must find the time slices per user. Say he/she worked from 10:00:00 to 10:09:59 and from 10:10:00 to 10:19:59 and from 10:00:00 to 10:29:59. That gives you three time slices: 10:00:00 to 10:09:59 (sessions 1 and 3), 10:10:00 to 10:19:59 (session 2 and 3) and 10:20:00 to 10:29:59 (session 3).
Then you count the sessions that were active in each time slice and remove slices were only three or less sessions were active. With those violated time slices found, you select the sessions that were active then.
Here is the complete statement:
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)
)
)
;
And here is the SQL fiddle: http://sqlfiddle.com/#!2/12c47/1 .
here is query which should do the trick:
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
this query is not very fast, but based on it you can de-normalize you db and obtain faster version
NOTE: there we can have problem if we have such data:
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
this is not actually an error, as there we 4 logins, then 1 logged out at 1:00 and then again 4th login to the system
both records will be displayed by query, depending on what you will be doing with results you can handle this situation differently
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.