在 Impala SQL 中获取时间戳行的差异,每次都会更新差异条件

Posted

技术标签:

【中文标题】在 Impala SQL 中获取时间戳行的差异,每次都会更新差异条件【英文标题】:Take difference of timestamp rows in Impala SQL where difference condition will be updated every time 【发布时间】:2021-09-18 12:11:03 【问题描述】:

我有一个示例表,它有 2 列,ID 和日期时间。

ID          Datetime            
123         12Sep2021 10:00       
123         12Sep2021 10:10
123         12Sep2021 10:25
123         12Sep2021 10:40
123         12Sep2021 10:52
123         12Sep2021 11:20
456         01Oct2021 09:00
456         01Oct2021 09:10
456         01Oct2021 09:40

我想创建一个新变量count,它将根据Datetime差异进行更新,如下所示:对于ID的第一次交易,count将为1。它将继续增加直到差异小于30分钟。如果差值大于 30 分钟,count 将再次设置为 1,对于此 ID 的下一个事务,将从具有 count 1 的 ID 中获取差值。结果输出如下:

ID          Datetime              Count      
123         12Sep2021 10:00        1
123         12Sep2021 10:10        2
123         12Sep2021 10:25        3
123         12Sep2021 10:40        1
123         12Sep2021 10:52        2 
123         12Sep2021 11:20        1
456         01Oct2021 09:00        1
456         01Oct2021 09:10        2
456         01Oct2021 09:40        1

我不确定如何在 Impala SQL 中完成它,因为它需要运行一个循环。我在 Python (Pandas) 中创建了如下相同的代码,但问题是 Pandas 需要将数据移动到驱动程序内存,由于数据量大,这是不可行的。所以我正在寻找 SQL 中的等效代码。请帮忙处理这个查询(这是等效的 Pandas 代码):

d=i:j.Datetime.to_numpy() for i,j in  df.groupby("ID")

    di=dict()
    
    for id in d.keys():
        n=1
        times=d[id]
        empty_list=list()
        first=times[0]
        for time in times:
            diff=time-first
            if diff >= np.timedelta64(30, 'm'):
                first=time
                n=1
            empty_list.append(n)
            di.update(id:empty_list)
            n=n+1

我不知道如何运行那种循环,有没有其他方法使用子查询来实现 Impala SQL 中的输出?

【问题讨论】:

不幸的是,在数据库中执行此操作需要某种分层或递归查询支持。尽管递归 CTE 是标准的一部分,但 Impala 不支持它们。 @mazaneicha 。 . .那不是OP要问的问题。 11:02 的时间将在第二组中,但您的方法不会包含它。 【参考方案1】:

这是在直接 sql 中执行此操作的一种方法。 我将前一个日期时间的值与当前日期时间进行比较,如果超过 30 分钟,我将开始使用 row_number 子句的新批次。

然后我复制间隔小于 30 分钟的 rnk 值。

最后,我得到由 grp 批处理的数据组,然后我使用计数器逻辑(使用 row_number 按 id、grp 分区)来生成计数器。

select y.*,row_number() over(partition by id,grp order by datetime) as cnt
from (
select x.*
       ,max(rnk) over(partition by id order by datetime) as grp
from (
    select id
           ,datetime
           ,case when lag(datetime) over(partition by id order by datetime) is null 
                   or datediff(datetime,lag(datetime) over(partition by id order by datetime))*24*60>=30 
                 then
                     row_number() over(partition by id order by datetime)
             end rnk
       from table
      )x
  )y

【讨论】:

。 .这很好用;这不是OP要问的问题。第 3 条和第 4 条记录仅相差 15 分钟,但开始一个新组。 谢谢戈登。问题是新组应该在它是第一条记录时开始,或者当前记录和第一行之间的差异大于 30 谢谢乔治。你能想到代码中的任何修改,因为输出需要新组在它是第一条记录时开始,或者第一行和当前行之间的差异大于 30,然后计数器将开始将该行作为参考,如所示的示例所示。再次感谢 不幸的是,如果没有递归,它将无法工作

以上是关于在 Impala SQL 中获取时间戳行的差异,每次都会更新差异条件的主要内容,如果未能解决你的问题,请参考以下文章

选择最近的时间戳行并从具有 Variant DataType 的列中获取值

创建行满足条件的 Impala 文本表

Impala 获得 2 个日期之间的差异,不包括周末

impala语句翻译过程中总结

Impala SQL - 获取最大时间戳记录 - 不产生结果

在 hive/impala sql 中按日期获取数据,