在 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 问题很少只有一个答案。
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 问题很少只有一个答案。