【问题标题】:Force UTC time in Snowflake JOIN condition在 Snowflake JOIN 条件下强制 UTC 时间
【发布时间】:2022-01-13 05:19:24
【问题描述】:

我有一个我们有的设置

  1. 带有 TIMESTAMP_LTZ (consumption_date) 类型列的登陆表。包括 +02:00 的时区
  2. 从登陆表读取的视图 (landing_view)
  3. 从具有 TIMESTAMP_NTZ (SOURCE_TIMESTAMP) 类型字段的表中读取的视图 (raw_data),但值本身采用 UTC 时间。

我必须使用消费日期和 SOURCE_TIMESTAMP 将来自landing_view 的数据连接到来自 raw_data 的数据。

SELECT l.ID, l.consumption_date, l.RUN_TIME, r.DISPLAY_NAME, r.source_timestamp, r.value_as_double
FROM "raw_data" r
JOIN "landing_view" l
ON r.SOURCE_TIMESTAMP >= DATEADD(second,120, convert_timezone('UTC',l.consumption_date))
  and r.SOURCE_TIMESTAMP < DATEADD(second,1000, convert_timezone('UTC',l.consumption_date))

我的问题是 convert_timezone 命令似乎根本不会影响连接子句,因为连接是使用 LTZ 类型中包含的本地时间 (+02:00) 进行的。

如果我使用 convert_timezone 是一个选择,如果可以正常工作,但对于 JOIN 则不行。

有没有办法让雪花在连接中使用 UTC?

【问题讨论】:

    标签: snowflake-cloud-data-platform utc timezone-offset


    【解决方案1】:

    这取决于您的 TIMEZONE 设置。请参见下面的示例。

    如果 TIMEZONE 是 UTC:

    alter session set TIMEZONE = 'UTC';
    select 
        -- 2AM UTC
        '2021-01-02 02:00:00'::timestamp_ntz as SOURCE_TIMESTAMP,
        -- 1AM UTC / 12PM Australia/Melbourne time / 1 hour before SOURCE_TIMESTAMP
        '2021-01-02 12:00:00 +1100'::timestamp_ltz as CONSUMPTION_DATE,
        -- so add one hour to CONSUMPTION_DATE should equal to SOURCE_TIMESTAMP
        SOURCE_TIMESTAMP = DATEADD(hour, 1, convert_timezone('UTC', CONSUMPTION_DATE)) as is_equal
    ;
    
    +-------------------------------+-------------------------------+----------+
    | SOURCE_TIMESTAMP              | CONSUMPTION_DATE              | IS_EQUAL |
    |-------------------------------+-------------------------------+----------|
    | 2021-01-02 02:00:00.000000000 | 2021-01-02 01:00:00.000 +0000 | True     |
    +-------------------------------+-------------------------------+----------+
    

    但是,如果您将 TIMEZONE 设置更改为另一个时区,结果会有所不同:

    alter session set TIMEZONE = 'Australia/Melbourne';
    select 
        -- 2AM UTC
        '2021-01-02 02:00:00'::timestamp_ntz as SOURCE_TIMESTAMP,
        -- 1AM UTC / 12PM Australia/Melbourne time / 1 hour before SOURCE_TIMESTAMP
        '2021-01-02 12:00:00 +1100'::timestamp_ltz as CONSUMPTION_DATE,
        -- so add one hour to CONSUMPTION_DATE should equal to SOURCE_TIMESTAMP
        SOURCE_TIMESTAMP = DATEADD(hour, 1, convert_timezone('UTC', CONSUMPTION_DATE)) as is_equal
    ;
    
    +-------------------------------+-------------------------------+----------+
    | SOURCE_TIMESTAMP              | CONSUMPTION_DATE              | IS_EQUAL |
    |-------------------------------+-------------------------------+----------|
    | 2021-01-02 02:00:00.000000000 | 2021-01-02 12:00:00.000 +1100 | False    |
    +-------------------------------+-------------------------------+----------+
    

    由于您的 SOURCE_TIMESTAMP 存储 UTC 值,您应该更改您的 TIMEZONE 设置以匹配它。

    顺便说一句,在 DATEADD 中包含 CONVERT_TIMEZONE 是多余的,因为它只会增加额外的操作,但不会产生任何影响。见下例:

    select 
        -- 1AM UTC / 9AM Australia/Perth time / 1 hour before SOURCE_TIMESTAMP
        '2021-01-02 09:00:00 +0800'::timestamp_ltz as CONSUMPTION_DATE,
        DATEADD(hour, 1, CONSUMPTION_DATE) as no_convert_tz,
        DATEADD(hour, 1, convert_timezone('UTC', CONSUMPTION_DATE)) as convert_tz,
        no_convert_tz = convert_tz
    ;
    
    +-------------------------------+-------------------------------+-------------------------------+----------------------------+
    | CONSUMPTION_DATE              | NO_CONVERT_TZ                 | CONVERT_TZ                    | NO_CONVERT_TZ = CONVERT_TZ |
    |-------------------------------+-------------------------------+-------------------------------+----------------------------|
    | 2021-01-02 12:00:00.000 +1100 | 2021-01-02 13:00:00.000 +1100 | 2021-01-02 02:00:00.000 +0000 | True                       |
    +-------------------------------+-------------------------------+-------------------------------+----------------------------+
    

    可以看到最后一列返回True。

    【讨论】:

    • 感谢 Eric,您的出色解释帮助我最终了解了雪花对日期时间的作用。最终结果是我去了数据的来源,在应用程序级别将其转换为 UTC,并将雪花时间戳类型更改为 NTZ。它更符合现有应用程序,无需转换任何内容。
    猜你喜欢
    • 1970-01-01
    • 2011-01-16
    • 2011-02-07
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多