mysql - 再次排行时差

时间:2017-06-17 22:29:53

标签: mysql sql

我正在尝试计算2行之间的时间差 - 但它比平常有点棘手。用户在进入时会收到temporally_id。此ID不是唯一的 - 这意味着在此用户离开后,新用户可能会在第一个用户离开后获得相同的temporally_id,但通常(请参阅下面的说明)。入口表看起来像这样(entrance_states - 1:enter,2:exit):

| temporally_id | entrance_state | entrance_date    |
-----------------------------------------------------
|    111        |       1        | 2017-01-01 10:20 |
|    222        |       1        | 2017-01-01 11:00 |
|    222        |       2        | 2017-01-01 11:20 |
|    222        |       1        | 2017-01-01 18:00 |
|    111        |       2        | 2017-01-01 21:00 |
|    111        |       1        | 2017-01-01 22:15 |
|    222        |       2        | 2017-01-02 01:00 |
|    111        |       2        | 2017-01-02 02:15 |

如您所见 - 用户也可以待到第二天。 我的愿望是以下结果:

| temporally_id | entrance_date    | timediff |
-----------------------------------------------
|    111        | 2017-01-01 10:20 | 11,50 h  |
|    222        | 2017-01-01 11:00 |  0,33 h  |
|    222        | 2017-01-01 18:00 |  7,00 h  |
|    111        | 2017-01-01 22:15 |  4,00 h  |

所以基本上我想要一个时差。最棘手的部分是有时候,“退出”没有被记录 - 所以在表中看起来状态1跟随另一个状态1之后的同一个temporally_id(这也是不正常的,不应该是)。因为我必须考虑这个失败并检查状态1是否跟随状态2.

这是我的SQL查询:

SELECT avg(TIMESTAMPDIFF(MINUTE,A.date,B.date)/60 ) as `diff`
FROM (SELECT 
        entrance_date as date,
        temporally_id
        FROM `entrance` 
        WHERE entrance_state = 1
        order by temporally_id asc, entrance_date asc ) A
LEFT JOIN        
     (SELECT 
        entrance_date as date, 
        temporally_id
        FROM `entrance` 
        WHERE  action_id = 2
        order by temporally_id asc, activity_date asc ) 
        B ON A.temporally_id = B.temporally_id

不幸的是,这并没有给我我需要的东西。

2 个答案:

答案 0 :(得分:0)

" temporally_id"是误用英语。你的意思是" temporary_id"。

你无法做到这一点" temporary_id"工作的想法,因为你不能原子地确定一个" temporary_id"未使用的重复使用它。因此,具有竞争条件,其中两个几乎同时进入的用户收到相同的" temporary_id"。

在任何情况下,如果你坚持尝试,那么你需要通过消除"退出"的情况来减少这个问题的复杂性。尚未登录。所以,让一个通过你的表,选择所有行"退出"没有记录,并设置他们的"退出"时间成为"条目"时间再加上,比方说,20分钟。 (通常的网络会话超时。)

答案 1 :(得分:0)

我建议您根据entrance_statetemporally_id处理记录,而不是根据entrance_date处理记录,例如:

SELECT *
FROM entrance
ORDER BY temporally_id, entrance_date

这将为您提供按ID和日期排序的结果,然后您可以在应用程序或存储过程中编写逻辑,以跟踪以前处理的记录,比较temporally_identrance_state对它的当前记录和输出/相应地忽略它。