다음을 통해 공유


DATEDIFF(Transact-SQL)

적용 대상: SQL Server Azure SQL 데이터베이스 Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System(PDW)

이 기능은 지정된 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입니다. 이 경우는 시작 시 시작한 다음 일 수를 계산 -2 하면 종료 2036-02-28 날짜에 도달한다는 것을 의미합니다.2036-03-01

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

startdate와 enddate가 모두 시간 값만 할당되고 datepart가 시간 datepartDATEDIFF가 아닌 경우 반환합니다0.

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

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

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

startdateenddate의 날짜 데이터 형식이 다르고 다른 데이터 형식보다 시간 부분 또는 소수 자릿수 초 정밀도가 더 DATEDIFF 많은 경우 누락된 부분을 다른 0부분으로 설정합니다.

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 및 enddate의 연도 값이 다르지만 달력 주 값 DATEDIFF 이 같으면 datepartweek에 대해 반환 0 됩니다.

설명

, WHERE, HAVINGGROUP BYORDER BY 절에 SELECT <list>사용합니다DATEDIFF.

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

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

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

예제

이 문서의 Transact-SQL 코드 샘플은 AdventureWorks2022 또는 AdventureWorksDW2022 샘플 데이터베이스를 사용하며, 이는 Microsoft SQL Server 예시 및 커뮤니티 프로젝트(Microsoft SQL Server Samples and Community Projects) 홈 페이지에서 다운로드할 수 있습니다.

이러한 예에서는 여러 유형의 식을 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;