【问题标题】:How to calculate difference in date in snowflake?如何计算雪花中的日期差异?
【发布时间】:2023-03-13 05:49:01
【问题描述】:

我有这两天:

BEFORE_DATETIME: 2021-09-02 09:41:00
AFTER_DATETIME: 2021-09-09 09:41:00

我需要计算这两天的差异。所以在这个例子中:7 天。但是,在 BEFORE_DATETIME,我有一些字符串值(坏记录)。由于这些记录,我在使用 DATEDIFF 函数时不断收到错误消息。

如何计算日期差异并忽略不良记录?

【问题讨论】:

    标签: sql snowflake-cloud-data-platform


    【解决方案1】:

    您可以使用TRY_TO_TIMESTAMP 函数将您的输入解析为时间戳,如果解析失败则返回NULL

    那么您可以随意申请您的DATEDIFF

    WITH cte AS (
      SELECT
         $1 AS before_datetime,
         $2 AS after_datetime
      FROM VALUES
      ('2021-09-02 09:41:00', '2021-09-09 09:41:00'),
      ('random_bad_record', '2021-09-09 09:41:00'),
      ('2021-09-02 09:41:00', 'random_bad_record')
    )
    SELECT
        TRY_TO_TIMESTAMP(before_datetime) as before_datetime,
        TRY_TO_TIMESTAMP(after_datetime) as after_datetime,
        DATEDIFF('days', TRY_TO_TIMESTAMP(before_datetime), TRY_TO_TIMESTAMP(after_datetime)) AS diff_in_days
    FROM cte
    ;
    

    【讨论】:

    • 您好,非常感谢!我认为这可行,但我有两列值(数千条记录),我需要在“FROM VALUES”下输入每一列吗?
    • 当然不是,FROM VALUE 只是为了在单个可读查询中重现您的用例。从您的角度来看,您只需要使用最终查询。我对其进行了更新,以便在最终查询中使用 TRY_TO_TIMESTAMP 并使其更适合您。
    • 道歉,你是对的!有效,非常感谢!非常感谢您的帮助!
    【解决方案2】:

    如果您使用TRY_TO_DATE 并且值“解析失败”,您将得到空值, 因此,您可以将该 TRY 的结果输入 DATEDIFF,或者您可以使用您跳过的内联 IFF,例如:

    IFF(TRY_TO_DATE(before_datetime) IS NOT NULL AND TRY_TO_DATE(after_datetime) IS NOT NULL, 
        DATEDIFF('days', before_datetime, after_datetime),
        0) AS alias_name
    

    当值不好时用你想要的替换0。等等

    【讨论】:

      【解决方案3】:

      我想补充一下关于这一点的讨论:

      我有一些字符串值(坏记录)。

      我看到不一致的日期/时间数据 - 从各种来源提取或由人以不同格式输入。如果你有这样的“坏”日期,这个 SQL UDF 就派上用场了。在最终尝试基本的 TRY_TO_TIMESTAMP 之前,它将尝试各种常见的日期和时间格式。如果它们都不起作用,它将返回 NULL。

      如果字符串字段中的日期格式不一致,则它更有可能转换日期,但应该在这种情况下使用,因为它会增加转换的开销。您可以查看该模式的工作原理,并将您自己的解析器添加到尝试列表中。

      create or replace function TRY_MULTI_TIMESTAMP(STR string)
      returns timestamp
      language SQL
      as
      $$
          case
              when STR RLIKE '[A-Za-z]{3} \\d{2} \\d{4} \\d{1,2}:\\d{2}:\\d{2}' then try_to_timestamp(left(STR, 20), 'MON DD YYYY HH24:MI:SS')
              when STR RLIKE '\\d{1,4}-\\d{1,2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2} [A|P][M]' then try_to_timestamp(STR, 'YYYY-MM-DD HH12:MI:SS AM')
              when STR RLIKE '\\d{1,2}/\\d{1,2}/\\d{4}' then try_to_timestamp(STR, 'mm/dd/yyyy')
              when STR RLIKE '\\d{1,2}\\/\\d{1,2}\\/\\d{4} \\d{1,2}:\\d{2}:\\d{2} [A-Za-z]{2}' then try_to_timestamp(STR, 'MM/DD/YYYY HH12:MI:SS AM')
              when STR RLIKE '\\d{1,2}\\/\\d{1,2}\\/\\d{4} \\d{1,2}:\\d{2}' then try_to_timestamp(STR, 'MM/DD/YYYY HH24:MI')
              when STR RLIKE '[A-Za-z]{3}, \\d{1,2} [A-Za-z]{3} \\d{4} \\d{1,2}:\\d{1,2}:\\d{1,2} [A-Za-z]{3}' then try_to_timestamp(left(STR, len(STR) - 4) || ' ' || '00:00', 'DY, DD MON YYYY HH:MI:SS TZH:TZM')   -- From Snowflake "LIST" command
              when STR RLIKE '\\d{1,2}/\\d{1,2}/\\d{2} \\d{1,2}:\\d{2} [A|P][M]' then try_to_timestamp(STR, 'MM/DD/YY HH12:MI AM')
              when STR RLIKE '[A-Za-z]{3} [A-Za-z]{3} \\d{2} \\d{4} \\d{1,2}:\\d{2}:\\d{2} GMT.*' then try_to_timestamp(left(replace(substr(STR, 5), 'GMT', ''), 26), 'MON DD YYYY HH:MI:SS TZHTZM')  -- Javascript
              else try_to_timestamp(STR) -- Final try without format specifier.
          end
      $$;
      
      select try_multi_timestamp('Sat Oct 02 2021 17:53:40 GMT+0000 (Coordinated Universal Time)'); -- JavaScript date format
      select try_multi_timestamp('Fri, 17 Apr 2020 17:55:45 GMT'); -- Snowflake LIST command file time
      select try_multi_timestamp('Oct 26 2021 6:25:15');
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-15
        • 2017-10-16
        • 2013-09-02
        • 2011-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多