【问题标题】:How do I calculate time difference between timestamps in the same column如何计算同一列中时间戳之间的时间差
【发布时间】:2018-02-19 19:06:43
【问题描述】:

我有一个 Oracle 数据库,其中机器人正在处理索赔。我有机器人 ID、声明 ID 和进程时间戳。我需要计算机器人从一个索赔到下一个索赔的时间。然后,我将需要显示在索赔之间花费超过 5 分钟的机器人,以及开始索赔的索赔 ID。举个例子:

Bot ID     Claim ID       Process Timestamp
123        12345          2/19/2018 12:45:26
123        12346          2/19/2018 12:55:11

机器人处理索赔 12345 的时间超过 5 分钟,因此我需要显示:

Bot ID     Claim ID       Minutes
123         12345         9:85

【问题讨论】:

  • 超前和滞后窗口函数可能有助于解决此问题。
  • 能否为您的数据库和您已经尝试过的代码提供示例创建代码?
  • 我没有创建数据库,我实际上是使用两个表来获取bot id、Claim id和进程时间戳的基本信息。我还没有弄清楚如何计算一列之间的时间差。我在网上搜索并找到了关于两列的信息,或者有一个额外的开始时间和结束时间字段的列,但这里都不存在。基本上,base 的代码是选择不同的 u.user_id 作为 BotID、c.claim_id、c.process_timestamp 从声明 c 加入用户 u 在 c.user_id = u.user_id where u.user_id like 'Bot%'

标签: sql oracle


【解决方案1】:

您可以使用lag() 的分析形式来查看机器人ID 的前一行,您在window 子句中将“previous”定义为基于时间戳。所以:

select bot_id, claim_id,
  process_timestamp - lag(process_timestamp)
    over (partition by bot_id order by process_timestamp) as elapsed
from your_table;

    BOT_ID   CLAIM_ID ELAPSED             
---------- ---------- --------------------
       123      12345                     
       123      12346 +00 00:09:45.000000 

从另一个中减去一个时间戳会给你一个间隔,你不能直接格式化,但你可以提取它的元素并将它们作为一个字符串粘在一起:

select bot_id, claim_id,
  extract(minute from elapsed) || ':' || extract(second from elapsed) as minutes
from (
  select bot_id, claim_id,
    process_timestamp - lag(process_timestamp)
      over (partition by bot_id order by process_timestamp) as elapsed
  from your_table
)
where elapsed > interval '5' minute;

    BOT_ID   CLAIM_ID MINUTES   
---------- ---------- ----------
       123      12346 9:45      

或者如果索赔可能超过一个小时:

select bot_id, claim_id,
  (60 * extract(hour from elapsed)) + extract(minute from elapsed)
    || ':' || extract(second from elapsed) as minutes
from (
...

如果该列实际上是日期而不是时间戳,则减法会给出数字而不是间隔。将其转换为字符串可以简单地通过将一天中的那一部分添加到午夜的名义日期来完成:

select bot_id, claim_id, to_char(date '1900-01-01' + elapsed, 'MI:SS') as minutes
from (
  select bot_id, claim_id,
    process_timestamp - lag(process_timestamp)
      over (partition by bot_id order by process_timestamp) as elapsed
  from your_table
)
where elapsed > 5/1440;

    BOT_ID   CLAIM_ID MINUTES   
---------- ---------- ----------
       123      12346 09:45     

如果它可能超过一个小时,那么您可以将格式模型设为HH24:MI:SS。 (从多个小时中获取分钟数,例如 120 分钟,稍微复杂一些。)

过滤器现在是 5/1440 - 一天有 1440 分钟,因此表示五分钟。

【讨论】:

  • 我喜欢这样,但是时间戳和机器人 ID 需要是相同的数据类型吗?我得到不一致的数据类型:预期日期得到数字。 Process_Timestamp 是数据类型 date,Bot ID 是数据类型 varchar。错误显示在 partition 关键字上,在这一行: c.process_timestamp - lag(c.process_timestamp, 1, 0) over (partition by u.bot_ID order by c.process_timestamp) as TimeDiff
  • 对;你说这是一个时间戳。减去日期会给出一个数字(一天的分数)而不是间隔,因此需要将该数字转换为字符串。 extract() 调用将引发该错误。与区间比较也行不通。
  • @DorindaMartineau - 更新了一个适用于日期的示例。在您的评论中,您有lag(c.process_timestamp, 1, 0);在该构造中,0 是在没有先前值的情况下使用的默认值,即代替 null。如果你真的想要那个,那么它需要是另一个日期,而不是一个数字。不过我不确定你是否这样做。
  • 亚历克斯·普尔,非常感谢。我想我现在已经为基础工作了,现在将对查询的其余部分工作。这是第一次使用延迟,但我相信这不会是我的最后一次,我现在可以与我的团队分享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多