최종 수정: 에
DATE_SUB
설명
DATE_SUB 함수는 날짜 또는 시간 값에서 지정된 시간 간격을 빼고 계산 결과를 반환합니다. DATE, DATETIME, TIMESTAMP_NS, TIMESTAMPTZ 입력을 지원하며, 시간 간격은 숫자 값과 단위로 정의합니다.
이 함수는 MySQL의 date_sub 함수와 동일하게 동작합니다.
별칭
- days_sub
- subdate
구문
DATE_SUB(<date_or_time_part>, INTERVAL <expr> <time_unit>)
매개변수
| 매개변수 | 설명 |
|---|---|
<date_or_time_part> | 유효한 날짜 값입니다. DATE, DATETIME, TIMESTAMP_NS, TIMESTAMPTZ를 지원합니다. 구체적인 형식은 timestamptz 변환, datetime 변환, date 변환을 참조하세요. |
<expr> | 뺄 시간 간격입니다. 독립 단위(예: YEAR)의 값은 INT 타입이고, 복합 단위(예: YEAR_MONTH)의 값은 STRING 타입이며, 숫자가 아닌 모든 문자를 구분자로 허용합니다. 따라서 예를 들어 INTERVAL 6/4 HOUR_MINUTE는 Doris에서 6시간 4분으로 해석되며, 1시간 30분(6/4 == 1.5)으로 해석되지 않습니다. 복합 단위에서 입력된 시간 간격 값이 너무 짧으면 더 큰 단위의 값은 0으로 설정됩니다. 이 값의 부호는 처음 나타나는 숫자가 아닌 문자가 -인지 여부만으로 결정됩니다. |
<time_unit> | 열거 값: YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, MINUTE, SECOND, YEAR_MONTH, DAY_HOUR, DAY_MINUTE, DAY_SECOND, DAY_MICROSECOND, HOUR_MINUTE, HOUR_SECOND, HOUR_MICROSECOND, MINUTE_SECOND, MINUTE_MICROSECOND, SECOND_MICROSECOND |
| time_unit | 예상 형식(숫자가 아닌 모든 문자를 구분자로 허용) |
|---|---|
| YEAR | 'YEARS' |
| QUARTER | 'QUARTERS' |
| MONTH | 'MONTHS' |
| WEEK | 'WEEKS' |
| DAY | 'DAYS' |
| HOUR | 'HOURS' |
| MINUTE | 'MINUTES' |
| SECOND | 'SECONDS' |
| MICROSECOND | 'MICROSECONDS' |
| YEAR_MONTH | 'YEARS-MONTHS' |
| DAY_HOUR | 'DAYS HOURS' |
| DAY_MINUTE | 'DAYS HOURS:MINUTES' |
| DAY_SECOND | 'DAYS HOURS:MINUTES:SECONDS' |
| DAY_MICROSECOND | 'DAYS HOURS:MINUTES:SECONDS.MICROSECONDS' |
| HOUR_MINUTE | 'HOURS:MINUTES' |
| HOUR_SECOND | 'HOURS:MINUTES:SECONDS' |
| HOUR_MICROSECOND | 'HOURS:MINUTES:SECONDS.MICROSECONDS' |
| MINUTE_SECOND | 'MINUTES:SECONDS' |
| MINUTE_MICROSECOND | 'MINUTES:SECONDS.MICROSECONDS' |
| SECOND_MICROSECOND | 'SECONDS.MICROSECONDS' |
반환 값
입력이 TIMESTAMP_NS이면 초 소수부 정밀도가 아홉 자리로 고정된 TIMESTAMP_NS를 반환합니다. 결과는 반환 타입의 범위를 기준으로 검증하며, TIMESTAMP_NS에는 [1677-09-21 00:12:43.145224192, 2262-04-11 23:47:16.854775807] 범위가 적용됩니다.
입력 날짜와 같은 타입의 계산 결과를 반환합니다:
- 입력이 DATE이면 DATE를 반환합니다(날짜 부분만 포함).
- 입력이 DATETIME이면 DATETIME을 반환합니다(날짜와 시간 포함).
- 입력이 TIMESTAMP_NS이면 초 소수부가 아홉 자리인 TIMESTAMP_NS를 반환합니다.
- 입력이 TIMESTAMPTZ이면 TIMESTAMPTZ를 반환합니다(날짜, 시간, 시간대 오프셋 포함).
- scale이 있는 datetime 타입은 해당 scale을 유지하여 반환합니다.
특수한 경우:
- 매개변수 중 하나라도 NULL이면 NULL을 반환합니다.
- expr이 잘못된 값(음수)이거나 time_unit이 유효하지 않으면 NULL을 반환합니다.
- 복합 단위에서 입력 구성 요소가 너무 많거나 구성 요소 중 하나라도 허용되는 최댓값 922337203685477579를 초과하면 오류를 반환합니다.
- 계산 결과가 날짜 타입에서 지원하는 최솟값보다 이르면(예: '0000-01-01' 이전) 오류를 반환합니다.
예제
-- Subtract two days
mysql> select date_sub(cast('2010-11-30 23:59:59' as datetime), INTERVAL 2 DAY);
+-------------------------------------------------------------------+
| date_sub(cast('2010-11-30 23:59:59' as datetime), INTERVAL 2 DAY) |
+-------------------------------------------------------------------+
| 2010-11-28 23:59:59 |
+-------------------------------------------------------------------+
-- Parameter with scale, return preserves scale
mysql> select date_sub('2010-11-30 23:59:59.6', INTERVAL 4 SECOND);
+------------------------------------------------------+
| date_sub('2010-11-30 23:59:59.6', INTERVAL 4 SECOND) |
+------------------------------------------------------+
| 2010-11-30 23:59:55.6 |
+------------------------------------------------------+
-- Subtract two months across years
mysql> select date_sub(cast('2023-01-15' as date), INTERVAL 2 MONTH);
+--------------------------------------------------------+
| date_sub(cast('2023-01-15' as date), INTERVAL 2 MONTH) |
+--------------------------------------------------------+
| 2022-11-15 |
+--------------------------------------------------------+
-- February 2023 has only 28 days, so subtracting one month from 2023-03-31 results in 2023-02-28
mysql> select date_sub('2023-03-31', INTERVAL 1 MONTH);
+------------------------------------------+
| date_sub('2023-03-31', INTERVAL 1 MONTH) |
+------------------------------------------+
| 2023-02-28 |
+------------------------------------------+
-- Subtract 61 seconds
mysql> select date_sub('2023-12-31 23:59:59', INTERVAL 61 SECOND);
+-----------------------------------------------------+
| date_sub('2023-12-31 23:59:59', INTERVAL 61 SECOND) |
+-----------------------------------------------------+
| 2023-12-31 23:58:58 |
+-----------------------------------------------------+
-- Subtract quarters
mysql> select date_sub('2023-12-31 23:59:59', INTERVAL 61 QUARTER);
+------------------------------------------------------+
| date_sub('2023-12-31 23:59:59', INTERVAL 61 QUARTER) |
+------------------------------------------------------+
| 2008-09-30 23:59:59 |
+------------------------------------------------------+
-- Example of TimeStampTz type, SET time_zone = '+08:00'
SELECT DATE_SUB('2024-02-05 02:03:04.123+12:00', INTERVAL 1 DAY);
+-----------------------------------------------------------+
| DATE_SUB('2024-02-05 02:03:04.123+12:00', INTERVAL 1 DAY) |
+-----------------------------------------------------------+
| 2024-02-03 22:03:04.123+08:00 |
+-----------------------------------------------------------+
-- Any parameter is NULL
mysql> select date_sub('2023-01-01', INTERVAL NULL DAY);
+-------------------------------------------+
| date_sub('2023-01-01', INTERVAL NULL DAY) |
+-------------------------------------------+
| NULL |
+-------------------------------------------+
-- For compound units, accept all non-numeric characters as separators.
select DATE_SUB('2025-10-23 10:10:10', INTERVAL ' *1@#$2' DAY_HOUR);
+----------------------------------------------------------------+
| DATE_SUB('2025-10-23 10:10:10', INTERVAL ' *1@#$2' DAY_HOUR) |
+----------------------------------------------------------------+
| 2025-10-22 08:10:10 |
+----------------------------------------------------------------+
-- For composite units, the sign of the time interval is determined only by whether the first non-digit character is `-`
-- All subsequent `-` are considered part of the delimiter
select
DATE_SUB('2025-10-23 10:10:10', INTERVAL '#-1:-1' MINUTE_SECOND) AS first_not_sub,
DATE_SUB('2025-10-23 10:10:10', INTERVAL ' -1:1' MINUTE_SECOND) AS first_sub;
+---------------------+---------------------+
| first_not_sub | first_sub |
+---------------------+---------------------+
| 2025-10-23 10:09:09 | 2025-10-23 10:11:11 |
+---------------------+---------------------+
-- For composite units, if the input time interval is too short, the value of the larger unit will be set to 0.
select DATE_SUB('2025-10-23 10:10:10', INTERVAL '1' MINUTE_SECOND) AS minute_interval_is_zero
+-------------------------+
| minute_interval_is_zero |
+-------------------------+
| 2025-10-23 10:10:09 |
+-------------------------+
-- If the number of time intervals input is excessive, return an error
select DATE_SUB('2025-10-23 10:10:10', INTERVAL '1:2:3.4' SECOND_MICROSECOND);
-- ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.3)[INVALID_ARGUMENT]Operation second_microsecond_add of -1:2:3.4 is invalid
-- For composite units, if the value of any part exceeds the maximum value of 922337203685477580
-- return an error
select DATE_SUB('2025-10-10 1:2:3', INTERVAL '922337203685477580' DAY_MICROSECOND);
-- ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.3)[E-218]Operation day_microsecond_add of 2025-10-10 01:02:03, -922337203685477580 out of range
-- Exceeds minimum date
mysql> select date_sub('0000-01-01', INTERVAL 1 DAY);
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.3)[E-218]Operation day_add of 0000-01-01, -1 out of range
select date_sub('9999-01-01', INTERVAL -1 YEAR);
ERROR 1105 (HY000): errCode = 2, detailMessage = (10.16.10.3)[E-218]Operation year_add of 9999-01-01, 1 out of range