 <p>This gives the averages Medians are a pain in SQL. <a href="http://stackoverflow.com/questions/1291152/simple-way-to-calculate-median-with-mysql">Simple way to calculate median with MySQL</a> gives some ideas. The two inner queries give the result sets to median over were there a median aggregate.</p> <pre><code>Select times.eventName, avg(times.timelapse) as avg_to_fail, avg(times2.timelapse) as avg_to_start From ( Select starts.id, starts.eventName, TimestampDiff(SECOND, starts.eventTime, Min(ends.eventTime)) as timelapse From Test as starts, Test as ends Where starts.eventName != 'start' And ends.eventName = 'start' And ends.eventTime &gt; starts.eventTime Group By starts.id ) as times2 Right Outer Join ( Select starts.id, ends.eventName, TimestampDiff(SECOND, starts.eventTime, Min(ends.eventTime)) as timelapse From Test as starts, Test as ends Where starts.eventName = 'start' And ends.eventName != 'start' And ends.eventTime &gt; starts.eventTime Group By starts.id ) as times On times2.EventName = times.EventName Group By Times.eventName </code></pre> <p>To aid understanding I'd first consider</p> <pre><code>Select starts.id, ends.eventName, starts.eventTime, ends.eventTime From Test as starts, Test as ends Where starts.eventName = 'start' And ends.eventName != 'start' And ends.eventTime &gt; starts.eventTime </code></pre> <p>This is the essence of the inner query <code>times</code> without the group by and the min statement. You'll see this has a row combining every start event with every end event where the end event is after the start event. Call this X.</p> <p>The next part is</p> <pre><code>Select X.startid, X.endeventname, TimestampDiff(SECOND, X.starttime, Min(x.endTime)) as timelapse From X Group By X.startid </code></pre> <p>The key here is that Min(x.endTime) combines with the group by. So we're getting the earliest end time after the start time (as X already constrained it to be after). Although I've only picked out the columns we need to use, we have access to start time id, end time id start event, end event, start time, min(end time) here. The reason you can adapt it to find the avg_to_start is because we pick the interesting event name, as we have both.</p> <p>SQL Fiddle: <a href="http://sqlfiddle.com/#!2/90465/6" rel="nofollow">http://sqlfiddle.com/#!2/90465/6</a></p>