다음을 통해 공유


DATEDIFF(Transact-SQL)

적용 대상:SQL 서버Azure SQL DatabaseAzure SQL Managed InstanceAzure Synapse Analytics분석 플랫폼 시스템(PDW)Microsoft Fabric의 SQL 데이터베이스

이 기능은 지정된 startdateenddate 사이에 지정된 datepart 경계의 수(부호 있는 정수 값으로)를 반환합니다.

startdate 값과 enddate 값 간의 더 큰 차이를 처리하는 함수는 DATEDIFF_BIG 참조하세요. 모든 Transact-SQL 날짜 및 시간 데이터 형식 및 함수에 대한 개요는 날짜 및 시간 데이터 형식 및 함수를 참조하세요.

Transact-SQL 구문 표기 규칙

구문

DATEDIFF ( datepart , startdate , enddate )

인수

datepart

startdate와 enddate의 차이를 보고하는 DATEDIFF 단위를 지정합니다. 일반적으로 사용되는 datepart 단위에는 month 또는 second가 포함됩니다.

datepart 값은 변수 또는 따옴표 붙은 문자열(예: 'month')으로 지정할 수 없습니다.

다음 표에는 올바른 datepart 값이 모두 나열되어 있습니다. DATEDIFF는 datepart전체 이름 또는 전체 이름의 나열된 약어를 허용합니다.

datepart 이름 datepart 약어
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y
day dd, d
week wk, ww
weekday dw, w
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs
nanosecond ns

해당 datepart 이름의 각 특정 datepart 이름 및 약어는 동일한 값을 반환합니다.

startdate

다음 값 중 하나를 확인할 수 있는 식입니다.

  • date
  • datetime
  • datetimeoffset
  • datetime2
  • smalldatetime
  • time

모호성을 피하려면 4자리 연도를 사용하세요. 두 자리 연도 값에 대한 자세한 내용은 서버 구성: 두 자리 연도 구분을 참조하세요.

enddate

startdate를 참조하세요.

반환 형식

int

반환 값

startdateenddate 사이의 int 차이로, datepart에 설정된 범위로 표시됩니다.

예를 들어 SELECT DATEDIFF(day, '2036-03-01', '2036-02-28'); 2036이 윤년이어야 했음을 나타내는 반환 -2입니다. 이 경우는 시작 시 시작한 다음 일 수를 계산 하면 종료 2036-03-01-2도달한다는 것을 의미합니다.2036-02-28

int에 대한 범위를 벗어난 반환 값의 경우(-2,147,483,648 to +2,147,483,647) DATEDIFF에서 오류를 반환합니다. 시작 millisecond날짜와 종료 날짜최대 차이는 24일, 20시간, 31분 및 23.647초입니다. 최대 second차이는 68년, 19일, 3시간, 14분, 7초입니다.

startdate

DATEDIFF는 반환 값을 계산하기 위해 startdate 또는 enddate의 표준 시간대 오프셋 구성 요소를 사용합니다.

smalldatetime은 분 단위로만 정확하기 때문에 startdate 또는 0에 smalldatetime 값이 있는 경우 초 및 밀리초는 항상 반환 값으로 설정 됩니다.

날짜 데이터 형식의 변수에 시간 값만 할당된 경우 DATEDIFF은 누락된 날짜 부분 값을 기본값인 1900-01-01로 설정합니다. 시간 또는 날짜 데이터 형식의 변수에 날짜 값만 할당될 경우 DATEDIFF는 누락된 시간 부분 값을 기본값인 00:00:00으로 설정합니다. startdate 또는 enddate 중 하나는 시간 부분만 있고 다른 하나는 날짜 부분만 있는 경우 DATEDIFF는 누락된 시간 및 날짜 부분을 기본값으로 설정합니다.

startdate누락된 부분을 다른 부분으로 설정합니다.

datepart 범위

다음 명령문은 동일한 startdate와 동일한 endate 값을 가집니다. 이 날짜는 서로 인접하며 100나노초(.0000001초)만큼 시간이 다릅니다. 각 문에서 startdateendate 사이의 차이는 해당 datepart에서 하나의 달력 또는 시간 범위를 넘어섭니다. 각 문은 1.

SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(weekday, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(microsecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');

startdate됩니다.

설명

, DATEDIFF, SELECT <list>WHEREHAVING 절에 GROUP BY사용합니다ORDER BY.

DATEDIFF는 문자열 리터럴을 datetime2 형식으로 암시적으로 캐스팅합니다. 즉, DATEDIFF 날짜가 문자열로 전달될 때 형식 YDM 을 지원하지 않습니다. 형식을 사용하려면 문자열 을 datetime 또는 smalldatetime 형식으로 명시적으로 캐스팅해야 YDM 합니다.

SET DATEFIRST 지정은 DATEDIFF에 영향을 주지 않습니다. DATEDIFF은 항상 일요일을 한 주의 첫 날로 사용하여 함수가 결정적으로 작동하게 합니다.

DATEDIFFenddate와 startdateminute차이가 int 범위를 벗어난 값을 반환하는 경우 전체 자릿수 이상으로 오버플로될 수 있습니다.

예제

이 문서의 코드 샘플은 AdventureWorks2025 또는 AdventureWorksDW2025 샘플 데이터베이스를 사용합니다. 이 데이터베이스는 Microsoft SQL Server 샘플 및 커뮤니티 프로젝트 홈페이지에서 다운로드할 수 있습니다.

이러한 예에서는 여러 유형의 식을 startdateenddate 매개 변수에 대한 인수로 사용합니다.

A. startdate 및 enddate에 대한 열 지정

이 예에서는 테이블의 두 열 사이에 겹쳐지는 날짜 범위의 수를 계산합니다.

CREATE TABLE dbo.Duration
(
    startDate DATETIME2,
    endDate DATETIME2
);

INSERT INTO dbo.Duration (startDate, endDate)
VALUES ('2007-05-06 12:10:09', '2007-05-07 12:10:09');

SELECT DATEDIFF(day, startDate, endDate) AS [Duration]
FROM dbo.Duration;

결과 집합은 다음과 같습니다.

Duration
--------
1

B. startdate 및 enddate에 대한 사용자 정의 변수 지정

이 예에서는 사용자 정의 변수가 startdateenddate 인수로 작용합니다.

DECLARE @startdate AS DATETIME2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate AS DATETIME2 = '2007-05-04 12:10:09.3312722';

SELECT DATEDIFF(day, @startdate, @enddate);

C. startdate 및 enddate에 대한 스칼라 시스템 함수 지정

이 예에서는 스칼라 시스템 함수를 startdateenddate 인수로 사용합니다.

SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());

D. startdate 및 enddate에 스칼라 하위 쿼리 및 스칼라 함수 지정

이 예에서는 스칼라 하위 쿼리 및 스칼라 함수를 startdateenddate 인수로 사용합니다.

USE AdventureWorks2022;
GO

SELECT DATEDIFF(day, (SELECT MIN(OrderDate)
                      FROM Sales.SalesOrderHeader), (SELECT MAX(OrderDate)
                                                    FROM Sales.SalesOrderHeader));

E. startdate 및 enddate에 대한 상수 지정

이 예에서는 문자 상수를 startdateenddate 인수로 사용합니다.

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', '2007-05-08 09:53:01.0376635');

F. enddate에 대한 숫자 식 및 스칼라 시스템 함수 지정

이 예에서는 (GETDATE() + 1) 숫자 식, GETDATE 스칼라 시스템 함수 및 SYSDATETIMEenddate 인수로 사용합니다.

USE AdventureWorks2022;
GO

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE() + 1) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO

USE AdventureWorks2022;
GO

SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day, 1, SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO

G. startdate에 대한 순위 함수 지정

이 예제에서는 순위 함수를 startdate 인수로 사용합니다.

USE AdventureWorks2022;
GO

SELECT p.FirstName,
       p.LastName,
       DATEDIFF(day, ROW_NUMBER() OVER (ORDER BY a.PostalCode), SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson AS s
     INNER JOIN Person.Person AS p
         ON s.BusinessEntityID = p.BusinessEntityID
     INNER JOIN Person.Address AS a
         ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
      AND SalesYTD <> 0;

H. startdate에 대한 집계 창 함수 지정

이 예에서는 집계 창 함수를 startdate 인수로 사용합니다.

USE AdventureWorks2022;
GO

SELECT soh.SalesOrderID,
       sod.ProductID,
       sod.OrderQty,
       soh.OrderDate,
       DATEDIFF(day, MIN(soh.OrderDate) OVER (PARTITION BY soh.SalesOrderID), SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail AS sod
     INNER JOIN Sales.SalesOrderHeader AS soh
         ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN (43659, 58918);
GO

9\. 날짜 부분 문자열로 startdate와 enddate 간의 차이점 찾기

-- DOES NOT ACCOUNT FOR LEAP YEARS
DECLARE @date1 AS DATETIME, @date2 AS DATETIME, @result AS VARCHAR (100);

DECLARE @years AS INT, @months AS INT, @days AS INT, @hours AS INT, @minutes AS INT, @seconds AS INT, @milliseconds AS INT;

SET @date1 = '1900-01-01 00:00:00.000';

SET @date2 = '2018-12-12 07:08:01.123';

SELECT @years = DATEDIFF(yy, @date1, @date2);

IF DATEADD(yy, -@years, @date2) < @date1
    SELECT @years = @years - 1;

SET @date2 = DATEADD(yy, -@years, @date2);

SELECT @months = DATEDIFF(mm, @date1, @date2);

IF DATEADD(mm, -@months, @date2) < @date1
    SELECT @months = @months - 1;

SET @date2 = DATEADD(mm, -@months, @date2);

SELECT @days = DATEDIFF(dd, @date1, @date2);

IF DATEADD(dd, -@days, @date2) < @date1
    SELECT @days = @days - 1;

SET @date2 = DATEADD(dd, -@days, @date2);

SELECT @hours = DATEDIFF(hh, @date1, @date2);

IF DATEADD(hh, -@hours, @date2) < @date1
    SELECT @hours = @hours - 1;

SET @date2 = DATEADD(hh, -@hours, @date2);

SELECT @minutes = DATEDIFF(mi, @date1, @date2);

IF DATEADD(mi, -@minutes, @date2) < @date1
    SELECT @minutes = @minutes - 1;

SET @date2 = DATEADD(mi, -@minutes, @date2);

SELECT @seconds = DATEDIFF(s, @date1, @date2);

IF DATEADD(s, -@seconds, @date2) < @date1
    SELECT @seconds = @seconds - 1;

SET @date2 = DATEADD(s, -@seconds, @date2);

SELECT @milliseconds = DATEDIFF(ms, @date1, @date2);

SELECT @result = ISNULL(CAST (NULLIF (@years, 0) AS VARCHAR (10)) + ' years,', '')
    + ISNULL(' ' + CAST (NULLIF (@months, 0) AS VARCHAR (10)) + ' months,', '')
    + ISNULL(' ' + CAST (NULLIF (@days, 0) AS VARCHAR (10)) + ' days,', '')
    + ISNULL(' ' + CAST (NULLIF (@hours, 0) AS VARCHAR (10)) + ' hours,', '')
    + ISNULL(' ' + CAST (@minutes AS VARCHAR (10)) + ' minutes and', '')
    + ISNULL(' ' + CAST (@seconds AS VARCHAR (10)) + CASE
        WHEN @milliseconds > 0
        THEN '.' + CAST (@milliseconds AS VARCHAR (10))
        ELSE ''
    END + ' seconds', '');

SELECT @result;

결과 집합은 다음과 같습니다.

118 years, 11 months, 11 days, 7 hours, 8 minutes and 1.123 seconds

예: Azure Synapse Analytics 및 분석 플랫폼 시스템(PDW)

이러한 예에서는 여러 유형의 식을 startdateenddate 매개 변수에 대한 인수로 사용합니다.

J. startdate 및 enddate에 대한 열 지정

이 예에서는 테이블의 두 열 사이에 겹쳐지는 날짜 범위의 수를 계산합니다.

CREATE TABLE dbo.Duration
(
    startDate DATETIME2,
    endDate DATETIME2
);

INSERT INTO dbo.Duration (startDate, endDate)
VALUES ('2007-05-06 12:10:09', '2007-05-07 12:10:09');

SELECT TOP (1) DATEDIFF(day, startDate, endDate) AS [Duration]
FROM dbo.Duration;
Duration
--------
1

11. startdate 및 enddate에 스칼라 하위 쿼리 및 스칼라 함수 지정

이 예에서는 스칼라 하위 쿼리 및 스칼라 함수를 startdateenddate 인수로 사용합니다.

-- Uses AdventureWorks
SELECT TOP (1) DATEDIFF(day, (SELECT MIN(HireDate)
                              FROM dbo.DimEmployee), (SELECT MAX(HireDate)
                                                      FROM dbo.DimEmployee))
FROM dbo.DimEmployee;

12. startdate 및 enddate에 대한 상수 지정

이 예에서는 문자 상수를 startdateenddate 인수로 사용합니다.

-- Uses AdventureWorks
SELECT TOP (1) DATEDIFF(day, '2007-05-07 09:53:01.0376635', '2007-05-08 09:53:01.0376635')
FROM DimCustomer;

13. startdate에 대한 순위 함수 지정

이 예제에서는 순위 함수를 startdate 인수로 사용합니다.

-- Uses AdventureWorks
SELECT FirstName,
       LastName,
       DATEDIFF(day, ROW_NUMBER() OVER (ORDER BY DepartmentName), SYSDATETIME()) AS RowNumber
FROM dbo.DimEmployee;

14. startdate에 대한 집계 창 함수 지정

이 예에서는 집계 창 함수를 startdate 인수로 사용합니다.

-- Uses AdventureWorks
SELECT FirstName,
       LastName,
       DepartmentName,
       DATEDIFF(year, MAX(HireDate) OVER (PARTITION BY DepartmentName), SYSDATETIME()) AS SomeValue
FROM dbo.DimEmployee;