获取两个相关行之间的时间增量

ber*_*rdt 1 postgresql

我有一个表,里面有很多成对的条目,通过一个字段name相互关联,每个条目都有一个时间戳timestamp_received。我想获得每个时间戳的增量name

桌子:

|id|name|timestamp_received|
|1|A|2016-09-21 11:11:00|
|2|A|2016-09-21 11:11:10|
|3|B|2016-09-21 11:11:20|
|4|B|2016-09-21 12:12:21|
Run Code Online (Sandbox Code Playgroud)

所需的输出:

|name|delta|
|A|00:00:10|
|B|01:01:01|
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的:

SELECT name, timestamp_received - LAG(timestamp_received, 1) OVER (PARTITION BY name ORDER BY id ASC) delta
FROM message;
Run Code Online (Sandbox Code Playgroud)

哪个不会产生预期的输出

SELECT fpm_left.name, age(fpm_right.timestamp_received, fpm_left.timestamp_received) 
FROM
  (SELECT * FROM message WHERE id IN (SELECT min(id) AS id FROM message GROUP BY name)) fpm_left
JOIN (SELECT * FROM message WHERE IN in (SELECT max(id) AS id FROM message GROUP BY name)) fpm_right
    ON fpm_left.name = fpm_right.name AND fpm_left.id != fpm_right.id;
Run Code Online (Sandbox Code Playgroud)

产生预期的输出,但似乎有点低效

这可以更优雅地完成吗?

a_h*_*ame 5

您可以使用带有窗口函数的解决方案,您只需要过滤掉“其他”行。这可以例如使用 Postgres' 完成distinct on ()

SELECT distinct on (name) 
       name, 
       timestamp_received - LAG(timestamp_received, 1) OVER (PARTITION BY name ORDER BY id ASC) as delta 
FROM message
order by name, timestamp_received desc;
Run Code Online (Sandbox Code Playgroud)

这将始终为每个名称选择一行(具有最新的行timestamp_received),即使每个名称有两行以上。