小编典典

Teradata中的分区窗口上的时差,以小时和秒为单位(会话记录)

sql

给定这样一个表:

cust_id                time
    123 2015-01-01 12:15:05
    123 2015-01-01 12:17:06
    123 2015-01-02 13:15:08
    123 2015-01-02 15:15:10
    456 2015-01-01 10:15:05
    456 2015-01-01 12:15:07
    456 2015-01-01 14:11:10

我想通过计算每个先前记录(思维lag函数)之间的时间差cust_id。我想要的输出:

cust_id                time diff_hours  diff_seconds
    123 2015-01-01 12:15:05       NULL          NULL
    123 2015-01-01 12:17:06       0.00           121
    123 2015-01-02 13:15:08       1.04         89882
    123 2015-01-02 15:15:10       0.08          7202
    456 2015-01-01 10:15:05       NULL          NULL
    456 2015-01-01 12:15:07       0.08          7202 
    456 2015-01-01 14:11:10       0.08          6963

如何在Teradata中完成此操作?

我已经尝试过类似的东西:

SELECT
  *
  , (time - time) OVER (PARTITION BY cust_id ORDER BY time ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)
FROM
  table_01

但是,尽管NULLs出现在预期的位置,但我会继续收到0.0其他所有结果。我一直在使用的包装也试着(time - time)SUM我已经尝试使用EXTRACT(SECOND FROM TIME)和其他几个变种-例如,试图地方DAY(4) to SECOND,但我似乎无法得到语法/排序/转换完全正确的,特别是折腾了窗函数到时混合。


阅读 173

收藏
2021-03-10

共1个答案

小编典典

LAGTeradata中没有,但是您可以重写它:

SELECT
  t.*
  , (time)
    - min(time) 
      OVER (PARTITION BY cust_id 
            ORDER BY time
            ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) SECOND(4)
FROM
  table_01 as t

当您尝试获取秒数时,您会遇到“间隔溢出”错误,即超过9999秒。更改DAY(4) TO SECOND或使用我几年前编写的此SQL
UDF来计算以秒为单位的两个时间戳之差:

REPLACE FUNCTION TimeStamp_Diff_Seconds
(
   ts1 TIMESTAMP(6)
  ,ts2 TIMESTAMP(6)
)
RETURNS DECIMAL(18,6)
LANGUAGE SQL
CONTAINS SQL
RETURNS NULL ON NULL INPUT
DETERMINISTIC
SQL SECURITY DEFINER
COLLATION INVOKER
INLINE TYPE 1
RETURN
(CAST((CAST(ts2 AS DATE)- CAST(ts1 AS DATE)) AS DECIMAL(18,6)) * 60*60*24)
      + ((EXTRACT(  HOUR FROM ts2) - EXTRACT(  HOUR FROM ts1)) * 60*60)
      + ((EXTRACT(MINUTE FROM ts2) - EXTRACT(MINUTE FROM ts1)) * 60)
      +  (EXTRACT(SECOND FROM ts2) - EXTRACT(SECOND FROM ts1))
;
2021-03-10