在 SQL Snowflake 中将时间戳截断为自定义时间单位

Truncate timestamp to custom unit of time in SQL Snowflake

Snowflake 中的函数 DATE_TRUNC(文档 here)允许您将给定的时间戳截断为给定的默认时间单位,可用:

 'YEAR', 'MONTH', 'DAY', 'HOUR', 'MINUTE' and 'SECOND'

举个例子:

DATE_TRUNC('MINUTE', '2015-05-08T23:39:35.123') --> 2015-05-08T23:39:00.000'

如果我们想将日期截断为自定义时间单位,我们将如何做,如:

 '5 MINUTE' OR '30 SECONDS'

例如,这些自定义时间将给出:

DATE_TRUNC('30 SECONDS', '2015-05-08T23:39:35.123') --> 2015-05-08T23:39:30.000'
DATE_TRUNC('30 SECONDS', '2015-05-08T23:39:15.123') --> 2015-05-08T23:39:00.000'

DATE_TRUNC('5 MINUTES', '2015-05-08T23:39:35.123') --> 2015-05-08T23:35:00.000'
DATE_TRUNC('5 MINUTES', '2015-05-08T23:34:35.123') --> 2015-05-08T23:30:00.000'

是否有解决方法或替代函数来获得这些结果?

谢谢

改为epoch seconds, division, floor,相乘

因此 30 秒步骤:

SELECT 
    TO_TIMESTAMP_NTZ('2015-05-08T23:39:35.123') as date
    ,DATE_PART(epoch_second, date) as epoch_sec
    ,floor(epoch_sec / 30) * 30 as epoch_in_30sec_steps
    ,TO_TIMESTAMP_NTZ(epoch_in_30sec_steps) as time_in_30sec_steps;

给出:

DATE EPOCH_SEC EPOCH_IN_30SEC_STEPS TIME_IN_30SEC_STEPS
2015-05-08 23:39:35.123 1431128375 1431128370 2015-05-08 23:39:30.000

因此 5 分钟是:

TO_TIMESTAMP_NTZ(floor(epoch_sec / 300) * 300) as time_in_5min_steps

西蒙说的。

你可以像这样把它放在一个漂亮的小 UDF 中

create or replace function trunc_by_seconds(num_seconds int, t timestamp_ntz(0))
returns timestamp_ntz(0)
as $$ to_timestamp_ntz(num_seconds * floor(date_part(epoch_second, t) / num_seconds))$$;

然后只需使用

select trunc_by_seconds(30, ...)

MOD() 方法,但是 epoch_sec 看起来更优雅、更简洁且同样有效。

我只是乐于寻找替代解决方案:-)

SELECT
  TO_TIMESTAMP_NTZ('2015-05-08T23:09:35.023') as date
   ,DATE_TRUNC( 'second',date) some_date_time
   ,TIMESTAMPADD(second, -MOD(DATE_PART (second,some_date_time),30), some_date_time)   as Time_In_30sec_Steps

SQL 问题很少只有一个答案。