【问题标题】:Get Impala equivalent of MONTHS_BETWEEN() in Snowflake在 Snowflake 中获取相当于 MONTHS_BETWEEN() 的 Impala
【发布时间】:2020-02-21 10:45:22
【问题描述】:

我在将查询从 Impala 迁移到 Snowflake 时遇到问题:

黑斑羚

SELECT period
    , now() as dt_today
    , MONTHS_BETWEEN(now(), period) as mb
FROM my_table

产量

period                  dt_today                        mb
--------------------------------------------------------------------------
2018-10-30T21:43:57Z    2020-02-21 10:21:12.827383000   15.709677419354838

雪花

SELECT period
    , CURRENT_TIMESTAMP() as dt_today
    , DATEDIFF('month', CURRENT_TIMESTAMP(), period) as mb
FROM my_table

产量

period                  dt_today                        mb
--------------------------------------------------------------------------
2018-10-30T21:43:57Z    2020-02-21 10:21:12.827383000   16

现在,从 Snowflake documentation 我了解到,当在 DATEDIFF 中指定 month 时,Snowflake 只会“使用从日期开始的月份和年份”这意味着差异不如 Impala 准确。 我尝试实现一个 proxy,例如获取月差,然后应用一些计算来获得浮点部分,但我仍然得到错误的月数:

DATEDIFF('month', period, CURRENT_TIMESTAMP()) + (GREATEST(DAY(period), DAY(CURRENT_TIMESTAMP())) -  LEAST(DAY(period), DAY(CURRENT_TIMESTAMP()))) / 31

以及以下内容以获得更精确的信息,但仍然不正确:

DATEDIFF('day', period, CURRENT_TIMESTAMP())/31 + (GREATEST(DAY(period), DAY(CURRENT_TIMESTAMP())) -  LEAST(DAY(period), DAY(CURRENT_TIMESTAMP()))) / 31

问题:如何在 Snowflake 中准确重现 Impala 的 MONTHS_BETWEEN()

【问题讨论】:

    标签: datediff snowflake-cloud-data-platform


    【解决方案1】:

    TL;DR

    IFF(DAY(DATE1) >= DAY(DATE2), DATEDIFF('month', DATE2, DATE1), DATEDIFF('month', DATE2, DATE1) - 1)
    +
    IFF(DAY(DATE1) >= DAY(DATE2), (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), day(DATE2))) / 31, 1 - (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), DAY(DATE2))) / 31)
    

    Impala MONTHS_BETWEEN(DATE1, DATE2) 函数的工作原理如下:

    • MONTHS_BETWEEN('2019-04-13', '2019-02-10') 产生 2.0967 (2 整月 + 3/31=0967)
    • MONTHS_BETWEEN('2019-04-13', '2019-02-03') 产生 1.7741 (1 整月 + 1-(7/31)=0967)

    现在我们知道 Snowflake DATEDIFF(DATE1, DATE3) 应用了一个简单的逐月操作:

    • DATEDIFF('month', '2019-04-13', '2019-02-10') 产生 2 (04 - 02)
    • DATEDIFF('month', '2019-04-13', '2019-02-03') 产生 2 (04 - 02)

    为了使用 Snowflake 函数获取 Impala 的 MONTHS_BETWEEN 的整数部分,我们应用以下逻辑:

    IFF(DAY(DATE1) >= DAY(DATE2), DATEDIFF('month', DATE2, DATE1), DATEDIFF('month', DATE2, DATE1) - 1)
    

    为了使用 Snowflake 函数获得 Impala 的 MONTHS_BETWEEN 的小数部分,我们应用以下逻辑:

    IFF(DAY(DATE1) >= DAY(DATE2), (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), day(DATE2))) / 31, 1 - (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), DAY(DATE2))) / 31)
    

    我们只需将它们加在一起即可得到 Impala 的确切值:

    IFF(DAY(DATE1) >= DAY(DATE2), DATEDIFF('month', DATE2, DATE1), DATEDIFF('month', DATE2, DATE1) - 1)
    +
    IFF(DAY(DATE1) >= DAY(DATE2), (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), day(DATE2))) / 31, 1 - (GREATEST(DAY(DATE1), DAY(DATE2)) - LEAST(DAY(DATE1), DAY(DATE2))) / 31)
    

    【讨论】:

      【解决方案2】:

      您的差异需要有多精确?

      因为我的第一个电话是减去两个日期(以天为单位) - 或者您可以使用 datediff 提取日期 - 然后从那里开始(如果近似值可以通过除以 30/31 或使用如果我需要精确的解决方案,可以进行一些更复杂的计算)

      您的解决方案不正确,因为如果您假设 12 月 31 日和 1 月 1 日,那么即使在随后的几天里,datediff 中的月份也会相差 1 - 这两个年份都会在 datediff 中给出“1”,月和日。

      【讨论】:

      • 我已经用我尝试过的另一个代理编辑了我的答案,但是我需要精确的精度,这很接近但不精确!
      • 嗯,在这种情况下,我会考虑像“检查完整的月数,使用 add_months 添加它们,检查您还需要添加多少天并使用它来获取小数部分“?
      【解决方案3】:

      Snowflake 原生支持它:4.42 Release Notes

      MONTHS_BETWEEN

      MONTHS_BETWEEN( <date_expr1> , <date_expr2> )
      

      返回两个 DATE 或 TIMESTAMP 值之间的月数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-28
        • 2021-07-26
        • 2017-09-21
        • 2013-12-22
        • 2018-11-08
        • 2023-02-16
        • 2011-02-24
        • 1970-01-01
        相关资源
        最近更新 更多