SQL-查找最早的A事件和第N个B事件之间的时间,其中A事件在第N-1个B事件之后

时间:2015-03-17 23:45:09

标签: mysql sql

使用SQL,我正在寻找第一个' A'之间的最大时间。事件和第一个' B'事件,直到' B'找到了一个新的事件,我希望找到一套新的' - ' B'事件。我只有2个活动,' A'和' B'。 ' A'在每个' B'之前至少会发射一次,但在B'之前可以无限次地发射。这可以反复重复。

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

时间结果我正在寻找:

(A1-B1): 6 
(A2-B2): 3
(A3-B3): 1

然后我可以找到这些时间的中位数和平均值。

我想过使用for循环来保存A直到找到B然后重新开始,但是我不确定如何开始循环。这是正确的想法吗?

我不能使用Min(Time)然后匹配行号,因为我必须将3个事件和10个A事件抛弃才能工作。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

这实际上与我今天早些时候(我当地时间)回答的another question非常相似,但有点扭曲。至少我的脑中有另一种解决方案,所以这很快就出现了:

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

使用您提供的样本数据,可得到以下结果:

Event   startTime   endTime totalTime
A       1           7       6 
A       9           12      3
A       14          15      1
MySQL 5.6中的

Here's a SQLFiddle

我觉得这可以改进(我不喜欢嵌套的GROUP BY条款),但我今天很累,所以我将这作为读者的潜在练习:

答案 1 :(得分:0)

  1. 对于每个A事件,您需要在之后找到B事件。
  2. 要找到下一个B事件,您需要找到最早的相应A事件。
  3. 利润。你可以减去时间等等......
  4. 这是最小的例子:

      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
    

    请参阅SQLFiddle demo

答案 2 :(得分:0)

我会推荐以下内容,假设时间是唯一的。对于每一个&#34; A&#34;事件,只包括下一个&#34; B&#34;事件。然后,对于那些时间,聚合:

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;