날짜 및 시간 값 작업하기¶
날짜 및 시간 계산은 분석 및 데이터 마이닝에서 가장 광범위하게 사용되는 가장 중요한 계산 중 하나입니다. 이 항목에서는 일반적인 날짜와 시간 쿼리 및 계산에 대한 실제 예를 제공합니다.
이 항목의 내용:
날짜 및 타임스탬프 로드하기¶
이 섹션에서는 날짜 및 타임스탬프 값을 로드하는 방법에 대한 예를 제공하고, 이러한 값을 로드할 때 타임존과 관련된 고려 사항을 설명합니다.
타임존이 연결되지 않은 타임스탬프 로드하기¶
다음 예에서 TIMESTAMP_TYPE_MAPPING 매개 변수는 TIMESTAMP_LTZ
(현지 타임존)로 설정됩니다. TIMEZONE 매개 변수는 America/Chicago
시간으로 설정됩니다. 일부 수신 타임스탬프에 지정된 타임존이 없는 경우 Snowflake는 타임스탬프가 TIMEZONE 매개 변수에 설정된 타임존의 현지 시간을 나타낸다고 가정하고 해당 문자열을 로드합니다.
ALTER SESSION SET TIMESTAMP_TYPE_MAPPING = 'TIMESTAMP_LTZ';
ALTER SESSION SET TIMEZONE = 'America/Chicago';
CREATE OR REPLACE TABLE time (ltz TIMESTAMP);
INSERT INTO time VALUES ('2024-05-01 00:00:00.000');
SELECT * FROM time;
+-------------------------------+
| LTZ |
|-------------------------------|
| 2024-05-01 00:00:00.000 -0500 |
+-------------------------------+
타임존이 연결된 타임스탬프 로드하기¶
다음 예에서 TIMESTAMP_TYPE_MAPPING 매개 변수는 TIMESTAMP_LTZ
(현지 타임존)로 설정됩니다. TIMEZONE 매개 변수는 America/Chicago
시간으로 설정됩니다. 일부 수신 타임스탬프에 다른 타임존이 지정된 경우 Snowflake는 문자열을 America/Chicago
시간으로 로드합니다.
ALTER SESSION SET TIMESTAMP_TYPE_MAPPING = 'TIMESTAMP_LTZ';
ALTER SESSION SET TIMEZONE = 'America/Chicago';
CREATE OR REPLACE TABLE time (ltz TIMESTAMP);
INSERT INTO time VALUES ('2024-04-30 19:00:00.000 -0800');
SELECT * FROM time;
+-------------------------------+
| LTZ |
|-------------------------------|
| 2024-04-30 22:00:00.000 -0500 |
+-------------------------------+
타임스탬프를 대체 타임존으로 변환하기¶
다음 예에서 타임스탬프 값 세트는 타임존 데이터를 제외하고 저장됩니다. 타임스탬프는 UTC 시간으로 로드되어 다른 타임존으로 변환됩니다.
ALTER SESSION SET TIMEZONE = 'UTC';
ALTER SESSION SET TIMESTAMP_LTZ_OUTPUT_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZH:TZM';
CREATE OR REPLACE TABLE utctime (ntz TIMESTAMP_NTZ);
INSERT INTO utctime VALUES ('2024-05-01 00:00:00.000');
SELECT * FROM utctime;
+-------------------------+
| NTZ |
|-------------------------|
| 2024-05-01 00:00:00.000 |
+-------------------------+
SELECT CONVERT_TIMEZONE('UTC','America/Chicago', ntz)::TIMESTAMP_LTZ AS ChicagoTime
FROM utctime;
+---------------------------+
| CHICAGOTIME |
|---------------------------|
| 2024-04-30 19:00:00 +0000 |
+---------------------------+
SELECT CONVERT_TIMEZONE('UTC','America/Los_Angeles', ntz)::TIMESTAMP_LTZ AS LATime
FROM utctime;
+---------------------------+
| LATIME |
|---------------------------|
| 2024-04-30 17:00:00 +0000 |
+---------------------------+
테이블의 날짜 열에 유효한 날짜 문자열 삽입하기¶
이 예에서는 DATE 열에 값을 삽입합니다.
CREATE OR REPLACE TABLE my_table(id INTEGER, date1 DATE);
INSERT INTO my_table(id, date1) VALUES (1, TO_DATE('2024.07.23', 'YYYY.MM.DD'));
INSERT INTO my_table(id) VALUES (2);
SELECT id, date1
FROM my_table
ORDER BY id;
+----+------------+
| ID | DATE1 |
|----+------------|
| 1 | 2024-07-23 |
| 2 | NULL |
+----+------------+
TO_DATE 함수에서는 TIMESTAMP 값 및 TIMESTAMP 형식의 문자열을 사용할 수 있지만, 시간 정보(시간, 분 등)는 무시됩니다.
INSERT INTO my_table(id, date1) VALUES
(3, TO_DATE('2024.02.20 11:15:00', 'YYYY.MM.DD HH:MI:SS')),
(4, TO_TIMESTAMP('2024.02.24 04:00:00', 'YYYY.MM.DD HH:MI:SS'));
SELECT id, date1
FROM my_table
WHERE id >= 3;
+----+------------+
| ID | DATE1 |
|----+------------|
| 3 | 2024-02-20 |
| 4 | 2024-02-24 |
+----+------------+
시간만으로 정의된 DATE를 삽입하는 경우의 기본 날짜는 1970년 1월 1일입니다.
INSERT INTO my_table(id, date1) VALUES
(5, TO_DATE('11:20:30', 'hh:mi:ss'));
SELECT id, date1
FROM my_table
WHERE id = 5;
+----+------------+
| ID | DATE1 |
|----+------------|
| 5 | 1970-01-01 |
+----+------------+
DATE 값을 검색할 때 그 형식을 TIMESTAMP 값으로 지정할 수 있습니다.
SELECT id,
TO_VARCHAR(date1, 'dd-mon-yyyy hh:mi:ss') AS date1
FROM my_table
ORDER BY id;
+----+----------------------+
| ID | DATE1 |
|----+----------------------|
| 1 | 23-Jul-2024 00:00:00 |
| 2 | NULL |
| 3 | 20-Feb-2024 00:00:00 |
| 4 | 24-Feb-2024 00:00:00 |
| 5 | 01-Jan-1970 00:00:00 |
+----+----------------------+
현재 날짜 및 시간 검색하기¶
현재 날짜를 DATE 값으로 가져오기:
SELECT CURRENT_DATE();
현재 날짜 및 시간을 TIMESTAMP 값으로 가져오기:
SELECT CURRENT_TIMESTAMP();
날짜 및 요일 검색하기¶
EXTRACT 함수를 사용하여 현재 요일을 숫자로 가져오기:
SELECT EXTRACT('dayofweek', CURRENT_DATE());
참고
dayofweek_iso
부분은 ISO-8601 데이터 요소 및 호환 형식 표준을 따릅니다. 이 함수는 요일을 1~7의 정수값(1은 월요일을 나타냄)으로 반환합니다.기타 시스템과의 호환성을 위해
dayofweek
부분은 UNIX 표준을 따릅니다. 이 함수는 요일을 0~6의 정수값(0은 일요일을 나타냄)으로 반환합니다.
TO_VARCHAR 또는 DECODE 함수를 사용하여 현재 요일을 문자열로 가져올 수 있습니다.
현재 날짜에 대한 짧은 영어 이름(예: “Sun”, “Mon” 등)을 반환하는 쿼리를 실행합니다.
SELECT TO_VARCHAR(CURRENT_DATE(), 'dy');
현재 날짜에 대해 명시적으로 제공된 요일 이름을 반환하는 쿼리를 실행합니다.
SELECT DECODE(EXTRACT('dayofweek_iso', CURRENT_DATE()),
1, 'Monday',
2, 'Tuesday',
3, 'Wednesday',
4, 'Thursday',
5, 'Friday',
6, 'Saturday',
7, 'Sunday') AS weekday_name;
날짜 및 시간 부분 검색하기¶
DATE_PART 함수를 사용하여 현재 날짜 및 시간에 대한 다양한 날짜 및 시간 부분을 가져올 수 있습니다.
당월의 현재 날짜에 대한 쿼리:
SELECT DATE_PART(day, CURRENT_TIMESTAMP());
현재 연도에 대한 쿼리:
SELECT DATE_PART(year, CURRENT_TIMESTAMP());
현재 달에 대한 쿼리:
SELECT DATE_PART(month, CURRENT_TIMESTAMP());
현재 시간에 대한 쿼리:
SELECT DATE_PART(hour, CURRENT_TIMESTAMP());
현재 분에 대한 쿼리:
SELECT DATE_PART(minute, CURRENT_TIMESTAMP());
현재 초에 대한 쿼리:
SELECT DATE_PART(second, CURRENT_TIMESTAMP());
EXTRACT 함수를 사용하면 현재 날짜 및 시간에 대한 다양한 날짜 및 시간 부분을 가져올 수도 있습니다.
당월의 현재 날짜에 대한 쿼리:
SELECT EXTRACT('day', CURRENT_TIMESTAMP());
현재 연도에 대한 쿼리:
SELECT EXTRACT('year', CURRENT_TIMESTAMP());
현재 달에 대한 쿼리:
SELECT EXTRACT('month', CURRENT_TIMESTAMP());
현재 시간에 대한 쿼리:
SELECT EXTRACT('hour', CURRENT_TIMESTAMP());
현재 분에 대한 쿼리:
SELECT EXTRACT('minute', CURRENT_TIMESTAMP());
현재 초에 대한 쿼리:
SELECT EXTRACT('second', CURRENT_TIMESTAMP());
이 쿼리는 현재 날짜 및 시간에 대한 다양한 날짜 및 시간 부분을 포함하는 테이블 형식의 출력을 반환합니다.
SELECT month(CURRENT_TIMESTAMP()) AS month,
day(CURRENT_TIMESTAMP()) AS day,
hour(CURRENT_TIMESTAMP()) AS hour,
minute(CURRENT_TIMESTAMP()) AS minute,
second(CURRENT_TIMESTAMP()) AS second;
+-------+-----+------+--------+--------+
| MONTH | DAY | HOUR | MINUTE | SECOND |
|-------+-----+------+--------+--------|
| 8 | 28 | 7 | 59 | 28 |
+-------+-----+------+--------+--------+
비즈니스 달력 날짜 및 시간 계산하기¶
DATE_TRUNC 함수를 사용하여 월의 첫 번째 날을 DATE 값으로 가져오기: 예를 들어, 현재 월의 첫 번째 날 가져옵니다.
SELECT DATE_TRUNC('month', CURRENT_DATE());
DATEADD 및 DATE_TRUNC 함수를 사용하여 이번 달의 마지막 날을 DATE 값으로 가져오기:
SELECT DATEADD('day',
-1,
DATE_TRUNC('month', DATEADD(day, 31, DATE_TRUNC('month',CURRENT_DATE()))));
대체 옵션의 경우, 다음 예에서는 DATE_TRUNC를 사용하여 이번 달의 시작을 검색하고 1개월을 더하여 다음 달의 시작을 검색한 후 1일을 빼서 현재 월의 마지막 날을 결정합니다.
SELECT DATEADD('day',
-1,
DATEADD('month', 1, DATE_TRUNC('month', CURRENT_DATE())));
이전 달의 마지막 날을 DATE 값으로 가져오기:
SELECT DATEADD(day,
-1,
DATE_TRUNC('month', CURRENT_DATE()));
현재 월의 짧은 영어 이름(예: “Jan”, “Dec” 등)을 가져옵니다.
SELECT TO_VARCHAR(CURRENT_DATE(), 'Mon');
명시적으로 제공된 월 이름을 사용하여 현재 월 이름을 가져옵니다.
SELECT DECODE(EXTRACT('month', CURRENT_DATE()),
1, 'January',
2, 'February',
3, 'March',
4, 'April',
5, 'May',
6, 'June',
7, 'July',
8, 'August',
9, 'September',
10, 'October',
11, 'November',
12, 'December');
이번 주의 월요일 날짜 가져오기:
SELECT DATEADD('day',
(EXTRACT('dayofweek_iso', CURRENT_DATE()) * -1) + 1,
CURRENT_DATE());
이번 주의 금요일 날짜 가져오기:
SELECT DATEADD('day',
(5 - EXTRACT('dayofweek_iso', CURRENT_DATE())),
CURRENT_DATE());
DATE_PART 함수를 사용하여 이번 달의 첫 번째 월요일 날짜 가져오기:
SELECT DATEADD(day,
MOD( 7 + 1 - DATE_PART('dayofweek_iso', DATE_TRUNC('month', CURRENT_DATE())), 7),
DATE_TRUNC('month', CURRENT_DATE()));
참고
위의 쿼리에서 7 + 1
의 1
값은 월요일로 해석됩니다. 첫 번째 화요일, 수요일 등에 대한 날짜를 검색하려면, Sunday
에서 7
까지 2
, 3
등으로 바꿉니다.
올해의 첫 번째 날을 DATE 값으로 가져오기:
SELECT DATE_TRUNC('year', CURRENT_DATE());
올해의 마지막 날을 DATE 값으로 가져오기:
SELECT DATEADD('day',
-1,
DATEADD('year', 1, DATE_TRUNC('year', CURRENT_DATE())));
작년의 마지막 날을 DATE 값으로 가져오기:
SELECT DATEADD('day',
-1,
DATE_TRUNC('year',CURRENT_DATE()));
이번 사분기의 첫 번째 날을 DATE 값으로 가져오기:
SELECT DATE_TRUNC('quarter', CURRENT_DATE());
이번 사분기의 마지막 날을 DATE 값으로 가져오기:
SELECT DATEADD('day',
-1,
DATEADD('month', 3, DATE_TRUNC('quarter', CURRENT_DATE())));
오늘의 자정에 대한 날짜 및 타임스탬프 가져오기:
SELECT DATE_TRUNC('day', CURRENT_TIMESTAMP());
+----------------------------------------+
| DATE_TRUNC('DAY', CURRENT_TIMESTAMP()) |
|----------------------------------------|
| Wed, 07 Sep 2016 00:00:00 -0700 |
+----------------------------------------+
날짜 및 시간 값 증분¶
DATEADD 함수를 사용하여 날짜 및 시간 값을 증가시킵니다.
오늘에 2년 추가:
SELECT DATEADD(year, 2, CURRENT_DATE());
오늘에 2일 추가:
SELECT DATEADD(day, 2, CURRENT_DATE());
현재 날짜 및 시간에 2시간 추가:
SELECT DATEADD(hour, 2, CURRENT_TIMESTAMP());
현재 날짜 및 시간에 2분 추가:
SELECT DATEADD(minute, 2, CURRENT_TIMESTAMP());
현재 날짜 및 시간에 2초 추가:
SELECT DATEADD(second, 2, CURRENT_TIMESTAMP());
유효한 문자열을 날짜, 시간 또는 타임스탬프로 변환하기¶
대부분의 경우, Snowflake는 문자열 형식의 날짜 및 타임스탬프 값을 올바르게 처리합니다. 문자열 기반 비교 또는 결과에서 세션 매개 변수에 설정된 형식과는 다른 타임스탬프 형식을 사용하는 경우와 같은 특정한 상황에서는 값을 원하는 형식으로 명시적으로 변환하여 예기치 않은 결과가 발생하는 것을 방지하는 것이 좋습니다.
예를 들어, 명시적으로 캐스팅하지 않고 문자열 값을 비교하면 다음과 같은 문자열 기반 결과가 제공됩니다.
CREATE OR REPLACE TABLE timestamps(timestamp1 STRING);
INSERT INTO timestamps VALUES
('Fri, 05 Apr 2013 00:00:00 -0700'),
('Sat, 06 Apr 2013 00:00:00 -0700'),
('Sat, 01 Jan 2000 00:00:00 -0800'),
('Wed, 01 Jan 2020 00:00:00 -0800');
다음 쿼리는 명시적 캐스팅 없이 비교를 수행합니다.
SELECT * FROM timestamps WHERE timestamp1 < '2014-01-01';
+------------+
| TIMESTAMP1 |
|------------|
+------------+
다음 쿼리는 DATE에 대한 명시적 캐스팅을 사용한 비교를 수행합니다.
SELECT * FROM timestamps WHERE timestamp1 < '2014-01-01'::DATE;
+---------------------------------+
| DATE1 |
|---------------------------------|
| Fri, 05 Apr 2013 00:00:00 -0700 |
| Sat, 06 Apr 2013 00:00:00 -0700 |
| Sat, 01 Jan 2000 00:00:00 -0800 |
+---------------------------------+
변환 함수에 대한 자세한 내용은 변환 함수의 날짜 및 시간 형식 을 참조하십시오.
날짜 문자열에 날짜 연산 적용하기¶
문자열로 표현된 날짜에 5일 더하기:
SELECT DATEADD('day',
5,
TO_TIMESTAMP('12-jan-2024 00:00:00','dd-mon-yyyy hh:mi:ss'))
AS add_five_days;
+-------------------------+
| ADD_FIVE_DAYS |
|-------------------------|
| 2024-01-17 00:00:00.000 |
+-------------------------+
DATEDIFF 함수를 사용하여 현재 날짜와 문자열로 표현된 날짜 사이의 차이를 계산할 수 있습니다.
TO_TIMESTAMP 함수를 사용하여 일수 차이를 계산합니다.
SELECT DATEDIFF('day',
TO_TIMESTAMP ('12-jan-2024 00:00:00','dd-mon-yyyy hh:mi:ss'),
CURRENT_DATE())
AS to_timestamp_difference;
+-------------------------+
| TO_TIMESTAMP_DIFFERENCE |
|-------------------------|
| 229 |
+-------------------------+
TO_DATE 함수를 사용하여 일수 차이를 계산합니다.
SELECT DATEDIFF('day',
TO_DATE ('12-jan-2024 00:00:00','dd-mon-yyyy hh:mi:ss'),
CURRENT_DATE())
AS to_date_difference;
+--------------------+
| TO_DATE_DIFFERENCE |
|--------------------|
| 229 |
+--------------------+
지정된 날짜에 1일 더하기:
SELECT TO_DATE('2024-01-15') + 1 AS date_plus_one;
+---------------+
| DATE_PLUS_ONE |
|---------------|
| 2024-01-16 |
+---------------+
현재 날짜에서 9일을 뺍니다(예: 2024년 8월 28일).
SELECT CURRENT_DATE() - 9 AS date_minus_nine;
+-----------------+
| DATE_MINUS_NINE |
|-----------------|
| 2024-08-19 |
+-----------------+
날짜 또는 시간 사이의 차이 계산하기¶
오늘과 3년 후 날짜 사이의 차이 계산:
SELECT DATEDIFF(year, CURRENT_DATE(),
DATEADD(year, 3, CURRENT_DATE()));
오늘과 3개월 후 날짜 사이의 차이 계산:
SELECT DATEDIFF(month, CURRENT_DATE(),
DATEADD(month, 3, CURRENT_DATE()));
오늘과 3일 후 날짜 사이의 차이 계산:
SELECT DATEDIFF(day, CURRENT_DATE(),
DATEADD(day, 3, CURRENT_DATE()));
현재 시간과 3시간 후 시간 사이의 차이 계산:
SELECT DATEDIFF(hour, CURRENT_TIMESTAMP(),
DATEADD(hour, 3, CURRENT_TIMESTAMP()));
현재 시간과 3분 후 시간 사이의 차이 계산:
SELECT DATEDIFF(minute, CURRENT_TIMESTAMP(),
DATEADD(minute, 3, CURRENT_TIMESTAMP()));
현재 시간과 3초 후 시간 사이의 차이 계산:
SELECT DATEDIFF(second, CURRENT_TIMESTAMP(),
DATEADD(second, 3, CURRENT_TIMESTAMP()));
연간 달력 뷰 만들기¶
CREATE OR REPLACE VIEW calendar_2016 AS
SELECT n,
theDate,
DECODE (EXTRACT('dayofweek',theDate),
1 , 'Monday',
2 , 'Tuesday',
3 , 'Wednesday',
4 , 'Thursday',
5 , 'Friday',
6 , 'Saturday',
0 , 'Sunday') theDayOfTheWeek,
DECODE (EXTRACT(month FROM theDate),
1 , 'January',
2 , 'February',
3 , 'March',
4 , 'April',
5 , 'May',
6 , 'June',
7 , 'July',
8 , 'August',
9 , 'september',
10, 'October',
11, 'November',
12, 'December') theMonth,
EXTRACT(year FROM theDate) theYear
FROM
(SELECT ROW_NUMBER() OVER (ORDER BY seq4()) AS n,
DATEADD(day, ROW_NUMBER() OVER (ORDER BY seq4())-1, TO_DATE('2016-01-01')) AS theDate
FROM table(generator(rowCount => 365)))
ORDER BY n ASC;
SELECT * from CALENDAR_2016;
+-----+------------+-----------------+-----------+---------+
| N | THEDATE | THEDAYOFTHEWEEK | THEMONTH | THEYEAR |
|-----+------------+-----------------+-----------+---------|
| 1 | 2016-01-01 | Friday | January | 2016 |
| 2 | 2016-01-02 | Saturday | January | 2016 |
...
| 364 | 2016-12-29 | Thursday | December | 2016 |
| 365 | 2016-12-30 | Friday | December | 2016 |
+-----+------------+-----------------+-----------+---------+