Reputation: 49
Using SQL, I'm looking for the largest times between the first 'A' event and the first 'B' event, until a 'B' event is found at which point I want to find a new set of 'A'-'B' events. I only have 2 events, 'A' and 'B'. 'A' will fire at least once before each 'B', but can fire an unlimited number of times before 'B'. This can repeat over and over.
Time | Event
1 | A <-This should be A1
3 | A
6 | A
7 | B <-This should be B1
9 | A <-This should be A2
10 | A
12 | B <-This should be B2
14 | A <-This should be A3
15 | B <-This should be B3
19 | A <-This A event has no ending B event yet
Time results I'm looking for:
(A1-B1): 6
(A2-B2): 3
(A3-B3): 1
Then I can find the median and average of these times.
I thought about using a for loop to save A until B is found and then start over, but I'm not sure how to even start that loop. Is that the right idea?
I can't use Min(Time) and then match up row numbers because I would have to throw out the A events at 3,6,and 10 for that to work.
Any help would be greatly appreciated.
Upvotes: 2
Views: 134
Reputation: 1270523
I would recommend the following, assuming the time is unique. For every "A" event, just include the time of the next "B" event. Then, for those times, aggregate:
select (@rn := @rn + 1),
min(time) as minAtime,
max(time) as maxAtime,
(next_btime - min(time)) as diff
from (select t.*,
(select t2.time
from table t2
where t2.event = 'B' and
t2.time > t.time
order by t2.time
) as next_Btime
from table t
where event = 'A'
) t cross join
(select @rn := 0) vars
group by next_Btime;
Upvotes: 2
Reputation: 242
Here is minimal example:
select min(aatime) atime, bbtime as btime
from
(
select aa._time as aatime, min(bb._time) as bbtime
from events aa left join events bb
on bb._time>aa._time and bb.event='B'
where aa.event='A'
group by aa._time
) bmin
group by bbtime
See SQLFiddle demo
Upvotes: 1
Reputation: 2436
This is actually very similar to another question I answered earlier today (my local time), but with a bit of a twist. At least I had the other solution fresh in my brain, so this popped out quick:
SELECT
Event,
MIN(startTime) AS startTime,
endTime,
endTime - StartTime AS totalTime
FROM
(SELECT
t1.Time AS startTime,
t1.Event,
MIN(t2.Time) AS endTime
FROM test_table t1
INNER JOIN test_table t2
ON t2.Time > t1.Time
AND t2.Event = 'B'
WHERE t1.Event = 'A'
GROUP BY t1.Time, t1.Event) AS eventSpread
GROUP BY Event, endTime
With the sample data you provided, this gives the following result:
Event startTime endTime totalTime
A 1 7 6
A 9 12 3
A 14 15 1
Here's a SQLFiddle in MySQL 5.6
I feel like this could be improved (I don't like the nested GROUP BY
clauses), but I am exhausted for today, so I'll leave that as a potential exercise for the reader :]
Upvotes: 1