返回MySQL

时间:2015-07-16 17:32:06

标签: mysql

目前,我有以下价值表:

--------------------------------
|   ID  |    Action    | Time  |
--------------------------------
|   1   |    A         | 01    |    
|   1   |    BB        | 10    |
|   1   |    C         | 12    |
|   2   |    C         | 05    |
|   2   |    A         | 08    |
|   2   |    BB        | 17    |
|   2   |    A         | 26    |
|   2   |    BB        | 47    |

假设数据按Time递增排列。 当数据按ID分组时,我想要为每个调用创建一个名为BB_Time的新列,该列具有BB的时间差和调用中的上一个事件,如下所示:

----------------------------
|   ID  |   ...   | BB_Time |
----------------------------
|   1   |   ...   |   09    |    
|   2   |   ...   |   21    |

如果BB在呼叫开始时发生,BB_Time将等于零,并且如果BB在呼叫中出现多次,则该列应返回最大时差。 编辑:如果BB没有出现在调用中,则NULL或0都可以。

我能够破解的最接近的(?)限制了BB条款中的WHERE次操作以及追踪时间,但是这并没有给出滞后。

思考?

2 个答案:

答案 0 :(得分:1)

以下是a fiddle that works,这是查询...

set @lastTime:=0;
set @lastId:=0;
select newId, max(TimeGap) from
    (select (myTime - if(@lastId=id,@lastTime,0)) TimeGap,
            (@lastTime:=myTime) NewTime, action,
            (@lastId:=id) newId from myTable
        order by id, myTime) AllTimeGaps
 where action = 'BB' group by newId

答案 1 :(得分:1)

有些人不相信会话变量,但我发现只要你小心他们相对可靠。免责声明:我认为MySQL没有正式定义评估SELECT结果字段的评估顺序。在实践中,它似乎总是从左到右,这个查询依赖于此,但是每当MySQL Server版本发生变化时,这都需要考虑/重新评估。另外,我在这里看到了其他相关的问题,这些问题表明这种查询可能不会很好玩#34;与VIEW s。

SELECT ID, MAX(BB_Time) AS BB_Time
FROM (
   SELECT ID, `Action`
   , @prevID := IFNULL(@prevID, 0) AS prevID
   , IF(`Action`<>'BB'
        , 0
        , IF(@prevID<>ID, 0, `Time` - IFNULL(@prevTime, `Time`))
     ) AS BB_Time
   , @prevTime := `Time`
   , @prevID := ID
   FROM the_table
   ORDER BY ID, `Time`
) AS subQ
GROUP BY ID
;

已更新以显示所有ID值,其中0表示没有BB操作的ID。

编辑:使用示例数据对其进行测试。第一次用0回来,第二次有效。可能需要在选择安全之前将@prev会话变量初始化为某些内容。