본문으로 건너뛰기
최종 수정: 에

DATE_SUB

설명​

DATE_SUB 함수는 주어진 날짜 또는 시간 값에서 지정된 시간 간격을 빼고 계산된 날짜 또는 시간 결과를 반환합니다. DATE(날짜만 포함), DATETIME(날짜와 시간 포함), TIMESTAMPTZ(날짜, 시간, 시간대 오프셋 포함) 타입의 연산을 지원하며, 시간 간격은 숫자 값과 단위로 정의합니다.

이 함수는 MySQL의 date_sub 함수와 동일하게 동작합니다.

별칭​

  • days_sub
  • subdate

구문​

DATE_SUB(<date_or_time_part>, INTERVAL <expr> <time_unit>)

매개변수​

매개변수설명
<date_or_time_part>유효한 날짜 값으로, datetime 또는 date 타입을 지원합니다. 구체적인 형식은 timestamptz 변환, datetime 변환, date 변환을 참조하세요.
<expr>뺄 시간 간격입니다. 단일 단위(예: YEAR)에는 INT 타입을 사용하고, 복합 단위(예: YEAR_MONTH)에는 STRING 타입을 사용하며 숫자가 아닌 모든 문자를 구분자로 허용합니다. 따라서 예를 들어 Doris는 INTERVAL 6/4 HOUR_MINUTE를 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'

반환 값​

계산된 결과를 date와 동일한 타입으로 반환합니다:

  • 입력이 DATE이면 DATE를 반환합니다(날짜 부분만 포함).
  • 입력이 DATETIME이면 DATETIME을 반환합니다(날짜와 시간 포함).
  • 입력이 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