目前,我有以下价值表:
--------------------------------
| 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
次操作以及追踪时间,但是这并没有给出滞后。
思考?
答案 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会话变量初始化为某些内容。