【问题标题】:Truncate timestamp to custom unit of time in SQL Snowflake在 SQL Snowflake 中将时间戳截断为自定义时间单位
【发布时间】:2022-01-14 08:35:16
【问题描述】:

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'

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

谢谢

【问题讨论】:

    标签: timestamp snowflake-cloud-data-platform truncate


    【解决方案1】:

    改为epoch seconds,除法,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
    

    【讨论】:

      【解决方案2】:

      西蒙说了什么。

      你可以像这样把它放在一个漂亮的小 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, ...)
      

      【讨论】:

      • UDF 的阻止缓存...所以从技术上讲是的,这是可行的,只是值得指出这可能会花费 $$,而缓存可以提供免费结果。
      【解决方案3】:

      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 问题。

      【讨论】:

      • hmm,代码块中的代码更具可读性,结果可以粘贴到表格或其他代码块中。但我喜欢选项。此外,您的图片没有显示最后的结果,重要的.. ;-)
      • 1000% 同意。正如我在第一句话中所说的 'epoch_sec 看起来更优雅' 。然而,正如您所知道的,每个问题都有大约 1000 个很酷的解决方案,如果我们都表现得像羊一样,只看最常见或最漂亮的解决方案,我们都会是一样的。我想想出新的和有趣的方法来解决问题 - 诚然 SO 不是这种行为的理想环境 - 我只希望只有一个人欣赏替代解决方案很酷并学到一些东西。今天就是你。
      • 对不起,我的意思是,粘贴代码图片几乎无法使用。请将其粘贴为代码块(用三个 ` 括起来)
      猜你喜欢
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多