날짜 및 시간 데이터 타입

이 항목에서는 날짜, 시간, 타임스탬프(날짜 + 시간 결합 형식) 관리를 위해 Snowflake에서 지원되는 데이터 타입을 설명합니다. 날짜, 시간, 타임스탬프 조작에 사용되는 문자열 상수에 대해 지원되는 형식도 설명합니다.

이 항목의 내용:

데이터 타입

DATE

Snowflake는 날짜를 저장하기 위한 단일 DATE 데이터 타입(시간 요소 없음)을 지원합니다.

DATE는 가장 일반적인 형식(YYYY-MM-DD, DD-MON-YYYY 등)의 날짜를 허용합니다.

또한, 허용되는 모든 TIMESTAMP 값은 날짜에 대해 유효한 입력입니다. 그러나 TIME 정보는 잘립니다.

DATE 및 TIMESTAMP 데이터의 경우 Snowflake는 1582년에서 9999년 사이의 연도를 사용할 것을 권장합니다. Snowflake는 이 범위 밖의 연도를 허용하지만, 그레고리력의 제한 으로 인해 1582년 이전 연도는 피해야 합니다.

DATETIME

DATETIME은 TIMESTAMP_NTZ의 별칭입니다.

TIME

Snowflake는 시간을 HH:MI:SS 형식으로 저장하기 위한 단일 TIME 데이터를 지원합니다.

TIME은 소수 초에 대한 선택적 정밀도 매개 변수를 지원합니다(예: TIME(3)). 시간 정밀도는 0(초)~9(나노초)의 범위로 지정할 수 있습니다. 기본 정밀도는 9입니다.

모든 TIME 값은 00:00:0023:59:59.999999999 사이의 값이어야 합니다. TIME은 내부적으로 “wallclock” 시간을 저장하며 TIME 값에 대한 모든 작업은 타임존을 고려하지 않고 수행됩니다.

TIMESTAMP

Snowflake에서 TIMESTAMP는 TIMESTAMP_* 변형 중 하나와 연결된 사용자 지정 별칭입니다. TIMESTAMP가 사용되는 모든 작업에서 연결된 TIMESTAMP_* 변형이 자동으로 사용됩니다. TIMESTAMP 데이터 타입은 테이블에 저장되지 않습니다.

TIMESTAMP와 연결된 TIMESTAMP_* 변형은 TIMESTAMP_TYPE_MAPPING 세션 매개 변수에 의해 지정됩니다. 기본값은 TIMESTAMP_NTZ입니다.

DATE 및 TIMESTAMP 데이터의 경우 Snowflake는 1582년에서 9999년 사이의 연도를 사용할 것을 권장합니다. Snowflake는 이 범위 밖의 연도를 허용하지만, 그레고리력의 제한 으로 인해 1582년 이전 연도는 피해야 합니다.

TIMESTAMP 별칭뿐 아니라 모든 타임스탬프 변형은 소수 초에 대한 선택적 정밀도 매개 변수도 지원합니다(예: TIMESTAMP(3)). 타임스탬프 정밀도는 0(초)~9(나노초)의 범위로 지정할 수 있습니다. 기본 정밀도는 9입니다.

TIMESTAMP_LTZ , TIMESTAMP_NTZ , TIMESTAMP_TZ

Snowflake는 타임스탬프의 세 가지 변형을 지원합니다.

TIMESTAMP_LTZ:

TIMESTAMP_LTZ는 내부적으로 지정된 정밀도로 UTC 시간을 저장합니다. 그러나 모든 작업은 TIMEZONE 세션 매개 변수로 제어되는 현재 세션의 타임존에서 수행됩니다.

TIMESTAMP_LTZ의 별칭:

  • TIMESTAMPLTZ

  • TIMESTAMP WITH LOCAL TIME ZONE

TIMESTAMP_NTZ:

TIMESTAMP_NTZ는 내부적으로 지정된 정밀도로 “wallclock” 시간을 저장합니다. 모든 작업은 타임존을 고려하지 않고 수행됩니다.

출력 형식에 타임존이 포함된 경우 UTC 표시기(Z)가 표시됩니다.

TIMESTAMP_NTZ가 TIMESTAMP의 기본값입니다.

TIMESTAMP_NTZ의 별칭:

  • TIMESTAMPNTZ

  • TIMESTAMP WITHOUT TIME ZONE

TIMESTAMP_TZ:

TIMESTAMP_TZ는 연결된 타임존 오프셋 과 함께 UTC 시간을 내부적으로 저장합니다. 타임존이 제공되지 않으면 세션 타임존 오프셋이 사용됩니다. 모든 작업은 각 레코드에 특정한 타임존 오프셋으로 수행됩니다.

TIMESTAMP_TZ의 별칭:

  • TIMESTAMPTZ

  • TIMESTAMP WITH TIME ZONE

TIMESTAMP_TZ 값은 UTC의 시간을 기준으로 비교됩니다. 예를 들어 다음과 같이 서로 다른 타임존의 서로 다른 시간을 비교할 때 두 값이 UTC로는 같은 시간이므로 TRUE가 반환됩니다.

select '2021-01-01 00:00:00 +0000'::timestamp_tz = '2021-01-01 01:00:00 +0100'::timestamp_tz;
Copy

주의

TIMESTAMP_TZ는 현재 주어진 값에 대해 생성되는 순간에 실제 타임존 이 아니라 주어진 타임존의 오프셋 만 저장합니다. 이는 UTC에서 사용하지 않는 일광 절약 시간을 처리할 때 특히 중요한 점입니다.

예를 들어 TIMEZONE 매개 변수를 "America/Los_Angeles" 로 설정한 상태에서 값을 주어진 연도의 1월에 TIMESTAMP_TZ로 변환하면 -0800 의 타임존 오프셋이 저장됩니다. 나중에 이 값에 6개월을 추가하면 7월에 로스앤젤레스에 대한 오프셋이 -0700 이더라도 -0800 오프셋이 유지됩니다. 이는 이 값이 생성된 후에는 실제 타임존 정보("America/Los_Angeles")를 더 이상 사용할 수 없기 때문입니다. 다음 코드 샘플에서 이 동작을 보여줍니다.

SELECT '2017-01-01 12:00:00'::TIMESTAMP_TZ;

-------------------------------------+
 '2017-01-01 12:00:00'::TIMESTAMP_TZ |
-------------------------------------+
 2017-01-01 12:00:00 -0800           |
-------------------------------------+

SELECT DATEADD(MONTH, 6, '2017-01-01 12:00:00'::TIMESTAMP_TZ);

--------------------------------------------------------+
 DATEADD(MONTH, 6, '2017-01-01 12:00:00'::TIMESTAMP_TZ) |
--------------------------------------------------------+
 2017-07-01 12:00:00 -0800                              |
--------------------------------------------------------+
Copy

타임스탬프 예

다양한 타임스탬프를 사용하여 테이블 만들기:

-- First, use TIMESTAMP (mapped to TIMESTAMP_NTZ)

ALTER SESSION SET TIMESTAMP_TYPE_MAPPING = TIMESTAMP_NTZ;

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP);

DESC TABLE ts_test;

+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
| name | type             | kind   | null? | default | primary key | unique key | check | expression | comment |
|------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------|
| TS   | TIMESTAMP_NTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    |
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+

-- Next, explicitly use one of the TIMESTAMP variations (TIMESTAMP_LTZ)

CREATE OR REPLACE TABLE ts_test(ts TIMESTAMP_LTZ);

DESC TABLE ts_test;

+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
| name | type             | kind   | null? | default | primary key | unique key | check | expression | comment |
|------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------|
| TS   | TIMESTAMP_LTZ(9) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    |
+------+------------------+--------+-------+---------+-------------+------------+-------+------------+---------+
Copy

다양한 타임존과 함께 TIMESTAMP_LTZ 사용하기:

CREATE OR REPLACE TABLE ts_test(ts timestamp_ltz);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test values('2014-01-01 16:00:00');
INSERT INTO ts_test values('2014-01-02 16:00:00 +00:00');

-- Note that the time for January 2nd is 08:00 in Los Angeles (which is 16:00 in UTC)

SELECT ts, hour(ts) FROM ts_test;

+---------------------------------+----------+
| TS                              | HOUR(TS) |
|---------------------------------+----------|
| Wed, 01 Jan 2014 16:00:00 -0800 |       16 |
| Thu, 02 Jan 2014 08:00:00 -0800 |        8 |
+---------------------------------+----------+

-- Next, note that the times change with a different time zone

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, hour(ts) FROM ts_test;

+---------------------------------+----------+
| TS                              | HOUR(TS) |
|---------------------------------+----------|
| Wed, 01 Jan 2014 19:00:00 -0500 |       19 |
| Thu, 02 Jan 2014 11:00:00 -0500 |       11 |
+---------------------------------+----------+
Copy

TIMESTAMP_NTZ 사용하기:

CREATE OR REPLACE TABLE ts_test(ts timestamp_ntz);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test values('2014-01-01 16:00:00');
INSERT INTO ts_test values('2014-01-02 16:00:00 +00:00');

-- Note that both times from different time zones are converted to the same "wallclock" time

SELECT ts, hour(ts) FROM ts_test;

+---------------------------+----------+
| TS                        | HOUR(TS) |
|---------------------------+----------|
| Wed, 01 Jan 2014 16:00:00 |       16 |
| Thu, 02 Jan 2014 16:00:00 |       16 |
+---------------------------+----------+

-- Next, note that changing the session time zone does not influence the results

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, hour(ts) FROM ts_test;

+---------------------------+----------+
| TS                        | HOUR(TS) |
|---------------------------+----------|
| Wed, 01 Jan 2014 16:00:00 |       16 |
| Thu, 02 Jan 2014 16:00:00 |       16 |
+---------------------------+----------+
Copy

TIMESTAMP_TZ 사용하기:

CREATE OR REPLACE TABLE ts_test(ts timestamp_tz);

ALTER SESSION SET TIMEZONE = 'America/Los_Angeles';

INSERT INTO ts_test values('2014-01-01 16:00:00');
INSERT INTO ts_test values('2014-01-02 16:00:00 +00:00');

-- Note that the January 1st record inherited the session time zone,
-- and "America/Los_Angeles" was converted into a numeric time zone offset

SELECT ts, hour(ts) FROM ts_test;

+---------------------------------+----------+
| TS                              | HOUR(TS) |
|---------------------------------+----------|
| Wed, 01 Jan 2014 16:00:00 -0800 |       16 |
| Thu, 02 Jan 2014 16:00:00 +0000 |       16 |
+---------------------------------+----------+

-- Next, note that changing the session time zone does not influence the results

ALTER SESSION SET TIMEZONE = 'America/New_York';

SELECT ts, hour(ts) FROM ts_test;

+---------------------------------+----------+
| TS                              | HOUR(TS) |
|---------------------------------+----------|
| Wed, 01 Jan 2014 16:00:00 -0800 |       16 |
| Thu, 02 Jan 2014 16:00:00 +0000 |       16 |
+---------------------------------+----------+
Copy

지원되는 달력

Snowflake는 모든 날짜와 타임스탬프에 그레고리력을 사용합니다. 그레고리력은 1582년부터 시작하는 달력이지만 이전 연도를 인식하며, 이는 Snowflake가 율리우스력과 일치하도록 1582년 이전의 날짜(또는 1582년 이전의 날짜를 포함하는 계산)를 조정하지 않으므로 유의해야 할 중요한 사항입니다. UUUU 형식 요소는 음수 연도를 지원합니다.

날짜 및 시간 형식

이러한 모든 데이터 타입은 가장 합리적이고 모호하지 않은 날짜, 시간 또는 날짜 + 시간 형식을 허용합니다. 형식을 자동으로 감지하도록 구성되어 있을 때 Snowflake가 인식하는 형식은 AUTO 감지에서 지원되는 형식 섹션을 참조하십시오.

또한 날짜 및 시간 형식을 수동으로 지정 할 수도 있습니다. 형식을 지정할 때 다음 표에 나열된 대/소문자를 구분하지 않는 요소를 사용할 수 있습니다.

형식 요소

설명

YYYY

4자리 숫자 연도입니다.

YY

TWO_DIGIT_CENTURY_START 세션 매개 변수로 제어되는 2자리 숫자 연도, 예: 1980 로 설정하면 7980 의 값은 각각 20791980 로 구문 분석됩니다.

MM

2자리 숫자 월(01=1월 등)입니다.

MON

전체 또는 간략한 월 이름입니다.

MMMM

전체 월 이름입니다.

DD

월의 2자리 숫자 일(01~31)입니다.

DY

간략한 요일입니다.

HH24

시간에 대한 2자리 숫자(00~23). AM / PM 을 지정하면 안 됩니다.

HH12

시간에 대한 2자리 숫자(01~12). AM / PM 을 지정할 수 있습니다.

AM , PM

오전(am)/오후(pm). HH12 와만 함께 사용하십시오(HH24 와 함께 사용하지 않음).

MI

분에 대한 2자리 숫자(00~59)입니다.

SS

초에 대한 2자리 숫자(00~59)입니다.

FF[0-9]

0(초) ~ 9(나노초) 정밀도의 소수 자리 초입니다. 예: FF, FF0, FF3, FF9. FF 를 지정하는 것은 FF9 (나노초)와 같습니다.

TZH:TZM , TZHTZM , TZH

타임존의 시 및 분이며, UTC 기준 차이입니다. + / - 를 기호의 접두사로 사용할 수 있습니다.

UUUU

ISO 형식 의 4자리 연도이며, BCE 연도의 경우 음수입니다.

참고

  • 날짜 전용 형식을 사용하는 경우 연결된 시간은 해당 날짜의 자정으로 간주됩니다.

  • 큰따옴표 사이에 있는 형식이나 위 요소 이외의 형식으로 된 항목은 모두 해석되지 않고 구문 분석/형식 지정됩니다.

  • 유효한 범위, 자릿수, 모범 사례에 대한 자세한 내용은 날짜, 시간 및 타임스탬프 형식 사용에 대한 추가 정보 섹션을 참조하십시오.

날짜 및 시간 형식 사용 예

다음은 “FF”를 사용하여 출력의 소수 초 필드에 9자리 숫자가 있어야 함을 나타내는 예입니다.

CREATE TABLE timestamp_demo_table(t  TIMESTAMP,
                                  t_tz TIMESTAMP_TZ,
                                  t_ntz TIMESTAMP_NTZ,
                                  t_ltz TIMESTAMP_LTZ);
INSERT INTO timestamp_demo_table (t, t_tz, t_ntz, t_ltz) VALUES (
    '2020-03-12 01:02:03.123456789',
    '2020-03-12 01:02:03.123456789',
    '2020-03-12 01:02:03.123456789',
    '2020-03-12 01:02:03.123456789'
    );
Copy
ALTER SESSION SET TIMESTAMP_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_TZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_NTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
ALTER SESSION SET TIMESTAMP_LTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF';
Copy
SELECT t, t_tz, t_ntz, t_ltz 
    FROM timestamp_demo_table;
+-------------------------------+-------------------------------+-------------------------------+-------------------------------+
| T                             | T_TZ                          | T_NTZ                         | T_LTZ                         |
|-------------------------------+-------------------------------+-------------------------------+-------------------------------|
| 2020-03-12 01:02:03.123456789 | 2020-03-12 01:02:03.123456789 | 2020-03-12 01:02:03.123456789 | 2020-03-12 01:02:03.123456789 |
+-------------------------------+-------------------------------+-------------------------------+-------------------------------+
Copy

날짜 및 시간 상수

상수 (리터럴 이라고도 함)는 고정 데이터 값을 가리킵니다. Snowflake는 문자열 상수를 사용하여 고정 날짜, 시간 또는 타임스탬프 값을 지정할 수 있도록 지원합니다. 문자열 상수는 항상 구분 기호 문자로 묶어야 합니다. Snowflake는 작은따옴표를 사용하여 문자열 상수를 구분할 수 있도록 지원합니다.

예:

date '2010-09-14'
time '10:03:56'
timestamp '2009-09-15 10:59:43'
Copy

이 문자열은 다음 매개 변수를 통해 설정된 바와 같이, 데이터 타입에 대한 입력 형식을 기준으로 DATE, TIME 또는 TIMESTAMP 값으로 구문 분석됩니다.

DATE:

DATE_INPUT_FORMAT

TIME:

TIME_INPUT_FORMAT

TIMESTAMP:

TIMESTAMP_INPUT_FORMAT

예를 들어 테이블의 열에 특정 날짜를 삽입하는 방법은 다음과 같습니다.

CREATE TABLE t1 (d1 DATE);

INSERT INTO t1 (d1) VALUES (DATE '2011-10-29');
Copy

간격 상수

간격 상수를 사용하여 날짜, 시간 또는 타임스탬프에 기간을 더하거나 뺄 수 있습니다. 간격 상수는 다음 구문을 가진 INTERVAL 키워드를 사용하여 구현됩니다.

{ + | - } INTERVAL '<integer> [ <date_time_part> ] [ , <integer> [ <date_time_part> ] ... ]'
Copy

모든 문자열 상수와 마찬가지로, Snowflake에는 간격 상수를 구분하는 작은따옴표가 필요합니다.

INTERVAL 키워드는 정수를 하나 이상 지원하며, 선택적으로 날짜 또는 시간 부분을 하나 이상 지원합니다. 예:

  • INTERVAL '1 YEAR' 는 1년을 나타냅니다.

  • INTERVAL '4 years, 5 months, 3 hours' 는 4년 5개월 3시간을 나타냅니다.

날짜 또는 시간 부분을 지정하지 않을 경우 간격은 초를 나타냅니다(예: INTERVAL '2'INTERVAL '2 seconds' 와 같음). 이는 날짜 산술을 수행하는 기본 시간 단위와는 다르다는 점에 유의하십시오. 자세한 내용은 이 항목의 날짜에 대한 간단한 산술 섹션을 참조하십시오.

지원되는 날짜 및 시간 부분의 목록은 이 항목에 있는 간격에 대해 지원되는 날짜 및 시간 부분 을 참조하십시오.

참고

  • 간격 증분 순서가 중요합니다. 나열된 순서대로 증분을 더하거나 뺍니다. 예:

    • INTERVAL '1 year, 1 day' 는 먼저 한 해를 더하거나 뺀 다음 하루를 더하거나 뺍니다.

    • INTERVAL '1 day, 1 year' 는 먼저 하루를 더하거나 뺀 다음 한 해를 더하거나 뺍니다.

    이는 윤년과 같은 달력 이벤트의 영향을 받는 계산에 영향을 줄 수 있습니다.

    SELECT TO_DATE ('2019-02-28') + INTERVAL '1 day, 1 year';
    
    +---------------------------------------------------+
    | TO_DATE ('2019-02-28') + INTERVAL '1 DAY, 1 YEAR' |
    |---------------------------------------------------|
    | 2020-03-01                                        |
    +---------------------------------------------------+
    
    SELECT TO_DATE ('2019-02-28') + INTERVAL '1 year, 1 day';
    
    +---------------------------------------------------+
    | TO_DATE ('2019-02-28') + INTERVAL '1 YEAR, 1 DAY' |
    |---------------------------------------------------|
    | 2020-02-29                                        |
    +---------------------------------------------------+
    
    Copy
  • INTERVAL은 데이터 타입이 아닙니다(즉, 테이블 열을 데이터 타입 INTERVAL이 되도록 정의할 수 없음). 간격은 날짜, 시간 및 타임스탬프 산술에만 사용할 수 있습니다.

간격에 대해 지원되는 날짜 및 시간 부분

INTERVAL 키워드는 다음의 날짜 및 시간 부분을 인자로 지원합니다(대/소문자 구분 안 함).

날짜 또는 시간 부분

약어/변형

year

y , yy , yyy , yyyy , yr , years , yrs

quarter

q , qtr , qtrs , quarters

month

mm , mon , mons , months

week

w , wk , weekofyear , woy , wy , weeks

day

d , dd , days, dayofmonth

hour

h , hh , hr , hours , hrs

minute

m , mi , min , minutes , mins

second

s , sec , seconds , secs

millisecond

ms , msec , milliseconds

microsecond

us , usec , microseconds

nanosecond

ns , nsec , nanosec , nsecond , nanoseconds , nanosecs , nseconds

간격의 예

특정 날짜에 연도 간격 추가하기:

select to_date('2018-04-15') + INTERVAL '1 year';

+-------------------------------------------+
| TO_DATE('2018-04-15') + INTERVAL '1 YEAR' |
|-------------------------------------------|
| 2019-04-15                                |
+-------------------------------------------+
Copy

특정 시간에 3시간 18분 간격 추가하기:

select to_time('04:15:29') + INTERVAL '3 hours, 18 minutes';

+------------------------------------------------------+
| TO_TIME('04:15:29') + INTERVAL '3 HOURS, 18 MINUTES' |
|------------------------------------------------------|
| 07:33:29                                             |
+------------------------------------------------------+
Copy

CURRENT_TIMESTAMP 함수의 출력에 복합적 간격 추가하기:

select current_timestamp + INTERVAL
                           '1 year, 3 quarters, 4 months, 5 weeks, 6 days, 7 minutes, 8 seconds,
                            1000 milliseconds, 4000000 microseconds, 5000000001 nanoseconds'
                        as complex_interval1;

+-------------------------------+
| COMPLEX_INTERVAL              |
|-------------------------------|
| 2020-12-28 08:08:01.325 -0800 |
+-------------------------------+
Copy

축약된 날짜/시간 부분 표기법으로 특정 날짜에 복합적 간격 추가하기:

select to_date('2025-01-17') + INTERVAL
                               '1 y, 3 q, 4 mm, 5 w, 6 d, 7 h, 9 m, 8 s,
                                1000 ms, 445343232 us, 898498273498 ns'
                            as complex_interval2;

+-------------------------+
| COMPLEX_INTERVAL2       |
|-------------------------|
| 2027-03-30 07:31:32.841 |
+-------------------------+
Copy

직원 정보 테이블을 쿼리하고 지난 2년 3개월 이내에 고용된 직원의 이름 반환하기:

select name, hire_date from employees where hire_date > current_date - INTERVAL '2 y, 3 month';
Copy

tl 로 명명된 테이블에서 ts 로 명명된 타임스탬프 열을 필터링하고 반환된 각각의 값에 4초 추가하기:

select ts + INTERVAL '4 seconds' from t1 where ts > to_timestamp('2014-04-05 01:02:03');
Copy

날짜에 대한 간단한 산술

간격 상수를 사용하여 날짜, 시간 및 타임스탬프에 더하거나 빼는 것 외에도, Snowflake는 { + | - } <정수> 형식으로 DATE 값에 대한 기본적인 더하기 및 빼기를 지원하는데, 여기서 <정수> 는 더하거나 뺄 일수를 지정합니다.

참고

TIME 및 TIMESTAMP 값은 아직 간단한 산술을 지원하지 않습니다.

날짜 산술의 예

특정 날짜에 1일 더하기:

select to_date('2018-04-15') + 1;

+---------------------------+
| TO_DATE('2018-04-15') + 1 |
|---------------------------|
| 2018-04-16                |
+---------------------------+
Copy

특정 날짜에서 4일 빼기:

select to_date('2018-04-15') - 4;

+---------------------------+
| TO_DATE('2018-04-15') - 4 |
|---------------------------|
| 2018-04-11                |
+---------------------------+
Copy

employees 로 명명된 테이블을 쿼리하고 퇴사했지만 365일 이상 근무했던 사람들의 이름 반환하기:

select name from employees where end_date > start_date + 365;
Copy