【问题标题】:Transpose timestamps to start & end timestamp columns将时间戳转置到开始和结束时间戳列
【发布时间】:2021-01-26 10:13:10
【问题描述】:

我有一系列带时间戳的记录,这些记录提供了地点的人数。这些不是定期的,每次检测到变化时都会给出计数。例如:

    TIMESTAMP         LOCATION       OCCUPANTS  
 ---------------- ----------------- ----------- 
  1602476920649    SOL2-5-MARS               4  
  1602476840140    SOL2-5-NEPTUNE           10  
  1602476821435    SOL2-4-SATURN             1  
  1602476709256    SOL2-4-SATURN             0  
  1602476505331    SOL2-5-NEPTUNE            8  
  1602476508223    SOL2-5-MARS               5  
  1602476438886    SOL2-4-JUPITER            4  

我想将此转换为具有每个位置的开始和结束时间戳的记录以及如下所示的人数。最后一个结束时间戳将是运行查询的当前时间戳。这必须使用 Oracle SQL。

     LOCATION         START_TS          END_TS        OCCUPANTS  
 ----------------- ---------------- ---------------- ----------- 
  SOL2-4-SATURN     1602476821435    1602476821435            0  
  SOL2-4-SATURN     1602476821435    1602477395000            1  
  SOL2-5-MARS       1602476508223    1602476920649            5  
  SOL2-5-MARS       1602476920649    1602477395000            4  
  SOL2-5-NEPTUNE    1602476505331    1602476840140            8  
  SOL2-5-NEPTUNE    1602476840140    1602477395000           10  
  SOL2-4-JUPITER    1602476753698    1602476753698            4  
  SOL2-4-JUPITER    1602476753698    1602477395000            4  

【问题讨论】:

    标签: sql oracle time-series


    【解决方案1】:

    您正在寻找LEAD。使用LEAD,您可以读取以下行的值。当没有下一行时,你会得到NULL。因此,每个位置的最后一行使用COALESCE

    select
      location,
      timestamp as start_ts,
      coalesce(
        lead(timestamp) over (partition by location order by timestamp),
        systimestamp) as end_ts,
      occupants
    from mytable
    order by location, timestamp;
    

    (此查询使用正确的时间戳。您的示例数据改为显示数字。如果您存储的是数字而不是时间戳,则必须将上述查询中的 SYSTIMESTAMP 转换为此类数字。)

    【讨论】:

    • 感谢Thorsten,这很好用:) 我的时间戳是自纪元以来的毫秒数,所以我正在转换如下:选择位置,时间戳,CAST(DATE '1970-01-01' + (1/24/ 60/60/1000) * timestamp AS TIMESTAMP) as start_ts, coalesce( lead(CAST(DATE '1970-01-01' + (1/24/60/60/1000) * timestamp AS TIMESTAMP)) over (partition by device_name order by CAST(DATE '1970-01-01' + (1/24/60/60/1000) * timestamp AS TIMESTAMP)), CAST(SYS_EXTRACT_UTC(systimestamp) AS TIMESTAMP)) as end_ts, mytable order by位置,时间戳;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-22
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多