1

我有一个存储用户和机器人(基本上是状态机)之间所有消息的表,我试图从这个表中找到所有消息/响应对,以计算每个用户的平均响应时间。需要注意的是,并非所有传出消息都会得到响应。

每行存储 message_id、user_id、created_at(时间戳)、state_code 和传出(布尔值)。

我一直在研究窗口函数,目的是使用延迟和引导来找到相关的消息对,然后计算它们的 created_at 值之间的差异,每个用户的平均值会给我们每个用户的平均值。响应时间。问题在于我无法确保两条消息都使用相同的 sate_code 发出。想法?

更新:如果用户的状态代码相同,您可以确保用户的消息是对给定传出消息的响应。所以,例如

╔════════════╦═════════╦════════════╦════════════╦══════════╗
║ message_id ║ user_id ║ created_at ║ state_code ║ outgoing ║
╠════════════╬═════════╬════════════╬════════════╬══════════╣
║          1 ║      11 ║ mm/dd/yy   ║         20 ║ t        ║
║          2 ║      11 ║ mm/dd/yy   ║         20 ║ f        ║
║          3 ║      11 ║ mm/dd/yy   ║         22 ║ t        ║
║          4 ║      11 ║ mm/dd/yy   ║         21 ║ t        ║
║          5 ║      12 ║ mm/dd/yy   ║         45 ║ t        ║
║          6 ║      12 ║ mm/dd/yy   ║         46 ║ f        ║
║          7 ║      12 ║ mm/dd/yy   ║         46 ║ t        ║
║          8 ║      12 ║ mm/dd/yy   ║         20 ║ f        ║
║          9 ║      12 ║ mm/dd/yy   ║         43 ║ t        ║
║         10 ║      13 ║ mm/dd/yy   ║         20 ║ t        ║
╚════════════╩═════════╩════════════╩════════════╩══════════╝

在这种情况下,这对是消息 1 和 2,以及消息 6 和 7。然而,只有消息 1 和 2 很重要,因为用户 1 从状态 20 响应我们在状态 20 中收到的传出消息之一。

4

1 回答 1

2

如果我理解正确,那么每次outgoing为假时,您都希望created_at前一行具有相同的user_idand state_code

我不确定您将如何为此使用 Windows 功能。这是一种使用相关子查询的方法:

这是一种方法:

select t.*,
       (select created_at
        from t t2
        where t2.user_id = t.user_id and
              t2.state_code = t.state_code and
              t2.outgoing = 't' and
              t2.created_at < t.created_at
        order by t2.created_at desc
        limit 1
       ) as prev_created_at
 from t

然后你可以做你的日期算术来得到你想要的(大部分prev_created_at不是NULL)。

如果您知道上一行是“前一行”,您可以执行类似的操作lag()

 select t.*
 from (select t.*,
              lag(created_at) over (partition by user_id, state_code order by created_at) as prev_created_at,
              lag(outgoing) over (partition by user_id, state_code order by created_at) as prev_outgoing
       from t
      ) t
where t.outgoing = 'f' and t.prev_outgoing = 't';
于 2013-07-11T00:15:31.967 回答