Sql Postgres:与机器人交互的平均用户响应时间
我有一个存储用户和机器人(基本上是一个状态机)之间所有消息的表,我试图从这个表中找到所有消息/响应对,以便计算每个用户的平均响应时间。需要注意的是,并非所有传出的消息都会得到响应 每行存储消息标识、用户标识、创建时间(时间戳)、状态代码和传出(布尔值) 我一直在研究窗口函数,目的是使用lag和lead找到相关的消息对,然后计算它们创建的_at值之间的差异,每个用户的平均值将给出每个用户的平均响应时间。问题是,我无法保证这两条消息都是使用相同的状态代码发出的。想法 更新:如果用户的消息具有相同的状态代码,则可以确保用户的消息是对给定传出消息的响应。比如说Sql Postgres:与机器人交互的平均用户响应时间,sql,database,postgresql,rails-postgresql,response-time,Sql,Database,Postgresql,Rails Postgresql,Response Time,我有一个存储用户和机器人(基本上是一个状态机)之间所有消息的表,我试图从这个表中找到所有消息/响应对,以便计算每个用户的平均响应时间。需要注意的是,并非所有传出的消息都会得到响应 每行存储消息标识、用户标识、创建时间(时间戳)、状态代码和传出(布尔值) 我一直在研究窗口函数,目的是使用lag和lead找到相关的消息对,然后计算它们创建的_at值之间的差异,每个用户的平均值将给出每个用户的平均响应时间。问题是,我无法保证这两条消息都是使用相同的状态代码发出的。想法 更新:如果用户的消息具有相同的状
╔════════════╦═════════╦════════════╦════════════╦══════════╗
║ 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时收到的一条传出消息。如果我理解正确,那么每次传出的
都是假的,您希望在上一行中使用相同的用户id
和状态代码创建
我不知道你会如何使用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
想不想给出一些示例数据或伪代码,显示消息相关和不相关的所需业务逻辑?当然,我只是添加了一些伪数据!难道你不想在OVER条款中使用ORDER BY吗?@MatBailie。清晰地谢谢你。+1-不是所有角落的案子都清楚。如果有一条传出状态20消息和一条传入状态20消息,但中间有其他消息,都是为同一用户发送的,那么这些消息是否仍然成对?无论哪种方式,这都应该给OP提供足够的工作空间,以满足实际需求:)谢谢大家!我没有足够的声誉来支持你的答案,但这帮了大忙!我最终使用了一个不太复杂的解决方案,在几个条件下将表与表本身连接起来。。。。再次感谢!
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';