HOWTO · PostgreSQL

PostgreSQL의 DATEADD()에 대한 대안

이 문서에서는 PostgreSQL의 DATEADD()에 대한 대안에 대해 설명합니다.

이 페이지의 내용

PostgreSQL은 SQL Server의 DATEADD() 구문을 사용하지 않습니다. 일수를 정수로 더하려면 manufacture_date + expires_in처럼 date에 정수를 더합니다. 월이나 연도 같은 달력 단위에는 date '2022-08-24' + INTERVAL '2 months'와 같이 INTERVAL을 사용합니다. 첫 번째 식의 결과는 date이고, date에 interval을 더하면 시간대가 없는 timestamp가 반환됩니다.

SQL의 DATEADD() 함수

제품 테이블에는 제조일과 만료일까지 남은 일수를 정수로 저장할 수 있습니다. 예를 들어 한 행에 manufacture_date = DATE '2022-08-24'와 expires_in = 10이 들어 있을 수 있습니다. 이 두 값으로 만료일을 계산하는 것이 목표입니다.

DATEADD()는 SQL Server에서 이 작업에 흔히 사용하는 함수입니다. SQL Server 구문은 DATEADD(day, 10, '2022-08-24')와 같습니다. 첫 번째 인수는 날짜 단위를 지정하고, 두 번째 인수는 더할 양을, 세 번째 인수는 시작 날짜를 지정합니다. 이 구문은 SQL Server에서 PostgreSQL로 넘어온 독자를 위한 비교 예시이며 PostgreSQL 쿼리가 아닙니다. PostgreSQL에서는 연산자와 interval로 날짜 산술을 표현합니다.

‘일을 더하는 것’과 ‘달력상 한 달을 더하는 것’은 서로 다른 작업이므로 이 차이가 중요합니다. 일수는 고정된 수의 달력 날짜입니다. 한 달에 포함된 일수는 달마다 다르므로, 월을 고정된 일수로 바꾸면 달력상 날짜가 잘못 계산될 수 있습니다. 필요한 단위에 맞는 PostgreSQL 구문을 선택하세요.

PostgreSQL에서 DATEADD() 대신 + 및 - 연산자 사용

일수를 더할 때 PostgreSQL에서는 정수를 date에 바로 더할 수 있습니다. DATE '2022-08-24' + 10 식은 열흘 뒤의 날짜를 계산합니다. DATE '2022-09-03' - 10처럼 일수를 뺄 수도 있고, DATE '2022-09-03' + (-10)처럼 음의 정수를 더해도 됩니다. 이들은 날짜 식이므로 결과는 계속 date이며 시간은 추가되지 않습니다.

이 간결한 방법은 expires_in 같은 정수형 열을 포함해 오프셋이 일수로 주어질 때 유용합니다. 예를 들어 manufacture_date + expires_in은 각 제품 행의 만료일을 계산합니다. 저장된 값이 일수를 나타내는지 확인하세요. 정수를 날짜에 더해도 월이나 연도를 뜻하지는 않습니다. 양이 매개변수라면 정수 산술과 호환되는 매개변수 유형을 사용하거나, 적절한 경우 정수로 형 변환하세요.

다음 Python 예제는 동일한 제조일과 저장된 일수를 사용해 만료일을 계산합니다.

from datetime import date, timedelta

manufacture_date = date(2022, 8, 24)
expires_in = 10
expiration_date = manufacture_date + timedelta(days=expires_in)
print(expiration_date.isoformat())
2022-09-03

이 Python 예제는 날짜 계산을 보여 주며 PostgreSQL SQL을 실행하지 않습니다. PostgreSQL 쿼리에서는 위에 나온 날짜 식을 사용하세요.

계산 단위가 달력상의 월, 연도, 주 또는 여러 단위의 조합이라면 interval을 사용하세요. 그러면 식에 의도한 단위가 드러나고 모든 달의 일수가 같다고 가정하지 않아도 됩니다.

PostgreSQL에서 DATEADD() 대신 INTERVAL 데이터 유형 사용

INTERVAL은 시간의 길이를 나타냅니다. 달력 기준 산술을 표현하려면 날짜에 interval을 더합니다. 예를 들어 DATE '2022-08-24' + INTERVAL '10 days', DATE '2022-08-24' + INTERVAL '2 months', DATE '2022-08-24' + INTERVAL '1 year'를 사용할 수 있습니다. DATE '2022-08-24' + INTERVAL '1 week'처럼 주 단위도 사용할 수 있습니다. PostgreSQL의 interval 리터럴에서는 단위 이름을 단수형이나 복수형으로 쓸 수 있습니다.

interval에는 INTERVAL '1 week 2 days'처럼 여러 단위를 함께 지정할 수 있습니다. 오프셋이 여러 달력 구성 요소로 이루어진 경우에 유용합니다. interval에는 시간, 분, 초도 포함할 수 있습니다. interval을 date에 더하면 PostgreSQL은 시간대가 없는 timestamp를 반환하므로 표시되는 값에는 일반적으로 자정을 나타내는 시간 구성 요소가 포함됩니다. 이후 애플리케이션에서 날짜만 필요하다면 결과를 명시적으로 date로 형 변환하세요.

달력 단위는 고정된 일수로 변환하지 않고 달력 산술을 따릅니다. 긴 달의 끝 무렵에 날짜에 한 달을 더하면 다음 달의 마지막 유효 날짜가 결과가 될 수 있습니다. 따라서 고정된 일수를 더한 결과와 다를 수 있습니다. 실제 데이터를 대표하는 날짜로 식을 확인하고 업무 규칙에 따라 월 또는 일을 선택하세요.

제품 예제에서는 저장된 일수에 하루짜리 interval을 곱합니다. manufacture_date + expires_in * INTERVAL '1 day'처럼 쓸 수 있습니다. 이 식은 각 행에 적용되며 interval이 포함되므로 timestamp를 반환합니다. 결과가 날짜 유형이어야 한다면 (manufacture_date + expires_in * INTERVAL '1 day')::date를 사용하세요. 월 수를 저장했다면 같은 방식으로 INTERVAL '1 month'를 사용하고, 열에 저장된 의미에 맞는 interval 단위를 선택하세요.

이 문서의 PostgreSQL 예제는 SQL 식이지만, 구성된 문서 실행 환경은 PostgreSQL 문을 실행하지 않습니다. 따라서 실행하지 않은 SQL 예시로 보고 PostgreSQL 데이터베이스에서 직접 실행하세요. DATEADD()는 SQL Server의 대응 구문을 설명하기 위한 용도로만 등장합니다. PostgreSQL 쿼리에서는 PostgreSQL의 +, -, INTERVAL 형식을 사용하세요.