postgresql SQL -查找周期和持续时间

atmip9wb  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(2)|浏览(218)

我在SQL(postgresql)中寻找解决方案。
我有一个日志表,其中包含以下列:
| 设备ID| id|代码|时间戳|
| - -----|- -----|- -----|- -----|
| 设备1| 1|十二岁|1672597471000|
| 设备1| 2|十一|1672597471001|
| 设备1| 3|八|1672597471002|
| 设备1| 4| 2| 1672597471003|
| 设备1| 5个|九个|1672597471004|
| 设备1|六|九个|电话:1672597471005|
| 设备1|七个|4| 1672597471006|
| 设备1|八|八|1672597471007|
| 设备1|九个|九个|1672597471008|
| 设备2| 1|八|1672597471000|
| 设备2| 2|九个|1672597471010|
| 设备2| 3|十二岁|1672597471050|
| 设备2| 4|八|电话:1672597471100|
| 设备2| 5个|九个|1672597471130|
我搜索一个(或多个)查询以查找两个代码(例如8和9)之间经过的时间。SQL查询的输出将是:
| 设备ID|经过时间|
| - -----|- -----|
| 设备1| 2|
| 设备1| 1|
| 设备2|十个|
| 设备2|三十|
如果有人能提出一些解决这个问题的想法,我将不胜感激。
我尝试使用导联功能,但我无法重置每个序列(8和9)之间的时间,并忽略唯一的8或9。简而言之,我被卡住了,我不知道这在SQL中是否可行。

smtd7mpg

smtd7mpg1#

这可以通过使用窗口函数lag()来获得当前行的前一行,然后使用条件where code = 9 and lag_code = 8进行减法以获得8和9之间的经过时间来实现:

with cte as (
  select *, 
            lag(timestamp) over (partition by deviceid order by timestamp) as lag_timestamp,
            lag(code) over (partition by deviceid order by timestamp) as lag_code
  from mytable
  where code between 8 and 9
)
select deviceId, timestamp - lag_timestamp as elapsed_time
from cte
where code = 9 and lag_code = 8

结果:
| 设备ID|经过时间|
| - -----|- -----|
| 设备1| 2|
| 设备1| 1|
| 设备2|十个|
| 设备2|三十|
Demo here

41ik7eoe

41ik7eoe2#

使用这个简单的查询来生成您需要的结果(和test it on fiddle):

select a.deviceId, (b.timestamp - a.timestamp) as elapsed_time
from logs a join logs b
on b.deviceid = a.deviceid
and b.id = (select min(id)
            from logs b
            where b.deviceid = a.deviceid
            and b.id > a.id
            and code = 9)
where a.code = 8;

并且它给出:

deviceid | elapsed_time 
----------+--------------
 device1  |            2
 device1  |            1
 device2  |           10
 device2  |           30

相关问题