SQL – 查找循环和持续时间

huangapple go评论58阅读模式
英文:

SQL - Find cycle and duration

问题

我在SQL(postgresql)中寻找解决方案来解决我的问题。

我有一个包含以下列的日志表:

设备ID ID 代码 时间戳
device1 1 12 1672597471000
device1 2 11 1672597471001
device1 3 8 1672597471002
device1 4 2 1672597471003
device1 5 9 1672597471004
device1 6 9 1672597471005
device1 7 4 1672597471006
device1 8 8 1672597471007
device1 9 9 1672597471008
device2 1 8 1672597471000
device2 2 9 1672597471010
device2 3 12 1672597471050
device2 4 8 1672597471100
device2 5 9 1672597471130

我寻找一个查询(或多个查询)来查找两个代码之间的经过的时间(例如8和9)。
SQL查询的输出将如下:

设备ID 经过的时间
device1 2
device1 1
device2 10
device2 30

如果有人能提供一些解决这个问题的想法,我将不胜感激。

我尝试过使用lead函数,但无法在每个序列(8和9)之间重置时间,并忽略唯一的8或9。简而言之,我陷入了困境,不知道在SQL中是否有可能实现这一目标。

英文:

I search a solution for my problem in SQL (postgresql).

I have a logs table with the following columns:

deviceId id code timestamp
device1 1 12 1672597471000
device1 2 11 1672597471001
device1 3 8 1672597471002
device1 4 2 1672597471003
device1 5 9 1672597471004
device1 6 9 1672597471005
device1 7 4 1672597471006
device1 8 8 1672597471007
device1 9 9 1672597471008
device2 1 8 1672597471000
device2 2 9 1672597471010
device2 3 12 1672597471050
device2 4 8 1672597471100
device2 5 9 1672597471130

I search one query (or more) to find the time elapsed between two codes (8 and 9 for example).
The output of SQL query will be:

deviceId elapsed time
device1 2
device1 1
device2 10
device2 30

I would really appreciate if anyone can suggest some ideas how to solve this problem.

I tried with lead function but i can't reset time between each sequence (8 and 9) and ignore unique 8 or 9. In short, i'm stuck and I don't know if it's possible in SQL.

答案1

得分: 1

以下是已翻译好的内容:

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

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

结果:

deviceid elapsed_time
device1 2
device1 1
device2 10
device2 30

示例链接

英文:

This can be accomplished by using the window function lag() to obtain the previous row of the current row, followed by subtraction to obtain the elapsed time between 8 and 9 using the condition where code = 9 and lag_code = 8:

 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

Result :

deviceid elapsed_time
device1 2
device1 1
device2 10
device2 30

Demo here

答案2

得分: 0

使用以下简单查询来获取您所需的结果(并在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
英文:

Use this simple query to produce the result you need (and 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;

and it gives:

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

huangapple
  • 本文由 发表于 2023年6月8日 20:52:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432053.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定