Postgres:与机器人交互的平均用户响应时间

时间:2013-07-10 23:19:40

标签: sql database postgresql rails-postgresql response-time

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

每一行都存储message_id,user_id,created_at(timestamp),state_code和outgoing(boolean)。

我一直在研究窗口函数,目的是使用滞后和导致找到相关的消息对,然后计算他们的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中接收到的一个外发消息。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,那么每当outgoing为false时,您希望前一行的created_at具有相同的user_idstate_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';
相关问题