Udostępnij za pomocą


DATEDIFF (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL Database w Microsoft Fabric

Funkcja ta zwraca liczbę (jako wartość całkowitą ze znakiem) określonych granic części daty przekroczonych między określoną datą startu a datą zakończenia.

Zobacz DATEDIFF_BIG funkcji, która obsługuje większe różnice między wartościami daty startu i daty zakończenia . Zobacz Typy danych i funkcje daty i godziny, aby zapoznać się z omówieniem wszystkich Transact-SQL typów i funkcji danych daty i godziny.

Transact-SQL konwencje składni

Składnia

DATEDIFF ( datepart , startdate , enddate )

Arguments

datepart

Określa jednostki, które DATEDIFF raportują różnicę między datą rozpoczęcia a datą zakończenia. Powszechnie stosowane jednostki datepart to month lub second.

Wartość datepart nie może być określona w zmiennej, ani jako cytatowany ciąg znaków jak 'month'.

Poniższa tabela przedstawia wszystkie ważne wartości datepart . DATEDIFF akceptuje albo pełną nazwę Datepart, albo dowolny podany skrót pełnego imienia i nazwiska.

nazwa składnika datepart skrót datypart
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

Każda konkretna nazwa datyczęści oraz skróty dla tej nazwy zwracają tę samą wartość.

data rozpoczęcia

Wyrażenie, które może rozpoznać jedną z następujących wartości:

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

Używaj czterocyfrowych lat, aby uniknąć niejednoznaczności. Zobacz konfigurację serwera: dwucyfrowy próg roku, aby uzyskać informacje o wartości dwucyfrowych lat.

enddate

Zobacz startdate.

Typy zwracane

int

Wartość zwracana

Różnica int między datą startu a datą zakończenia, wyrażona w granicy wyznaczonej przez datepart.

Na przykład zwroty SELECT DATEDIFF(day, '2036-03-01', '2036-02-28');-2, co sugeruje, że 2036 musi być rokiem przestępnym. W takim przypadku oznacza, że jeśli zaczniemy od daty 2036-03-01, a następnie policzymy -2 dni, osiągniemy datę końcową .2036-02-28

Dla wartości zwrotnej poza zakresem int (-2,147,483,648 do +2,147,483,647) DATEDIFF zwraca błąd. Dla millisecond, maksymalna różnica między datą startu a datą zakończenia wynosi 24 dni, 20 godzin, 31 minut i 23,647 sekundy. Dla second, maksymalna różnica wynosi 68 lat, 19 dni, 3 godziny, 14 minut i 7 sekund.

Jeśli data startu i data zakończenia są przypisane tylko do wartości czasowej, a data część nie jest częścią data time, DATEDIFF zwraca 0.

DATEDIFF do obliczenia wartości zwrotnej wykorzystuje składnik strefy czasowej (offset) (data startu lub data zakończenia ).

Ponieważ smalldatetime jest dokładny tylko co do minuty, sekundy i milisekundy są zawsze ustawiane w 0 wartości zwrotnej, gdy data startu lub data końca mają wartość smalldatetime .

Jeśli tylko wartość godziny jest przypisana do zmiennej typu danych daty, DATEDIFF ustawia wartość brakującej części daty na wartość domyślną: 1900-01-01. Jeśli tylko wartość daty jest przypisana do zmiennej typu danych godziny lub daty, DATEDIFF ustawia wartość brakującej części godziny na wartość domyślną: 00:00:00. Jeśli data początkowa lub data końcowa mają tylko część czasową, a druga tylko część daty, DATEDIFF ustawia brakujące części godziny i daty na wartości domyślne.

Jeśli data startu i data zakończenia mają różne typy danych datowych, a jeden z nich ma większą precyzję czasową lub ułamkowych sekund niż drugi, DATEDIFF to brakujące części drugiego na .0

Granice DatePart

Poniższe instrukcje mają te same wartości startdate i te same wartości enddate . Te daty są sąsiednie i różnią się czasowo o sto nanosekund (0,0000001 sekundy). Różnica między wartością startdate i enddate w każdej instrukcji przekracza jeden kalendarz lub granicę godziny części daty. Każde zdanie zwraca 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');

Jeśli data startu i data zakończenia mają różne wartości roku, ale mają te same wartości tygodnia kalendarzowego, DATEDIFF zwraca 0 się dla częściweek daty.

Uwagi

Użycie DATEDIFF w SELECT <list>, WHERE, HAVING, GROUP BY, oraz ORDER BY zdaniach.

DATEDIFF niejawnie rzutuje literały ciągu jako typ datetime2 . Innymi słowy, nie obsługuje formatuDATEDIFF, YDM gdy data jest przekazywana jako ciąg znaków. Aby użyć formatu, musisz wyraźnie przypisać ciąg znaków do typu datetime lub YDM.

Określanie SET DATEFIRST nie ma wpływu na .DATEDIFF DATEDIFF zawsze używa niedzieli jako pierwszego dnia tygodnia, aby zapewnić, że funkcja działa w sposób deterministyczny.

DATEDIFF może przepełnić z precyzją lub minute wyższą, jeśli różnica między datą zakończenia a datą startu zwraca wartość wykraczającą poza zakres dla int.

Przykłady

Przykłady kodu w tym artykule korzystają z przykładowej bazy danych AdventureWorks2025 lub AdventureWorksDW2025, którą można pobrać ze strony głównej Przykładów programu Microsoft SQL Server i projektów społeczności.

Przykłady te wykorzystują różne typy wyrażeń jako argumenty dla parametrów daty startu i daty zakończenia .

A. Określ kolumny dla daty startu i daty zakończenia

Ten przykład oblicza liczbę granic dni przeciętych między datami w dwóch kolumnach tabeli.

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;

Oto zestaw wyników.

Duration
--------
1

B. Określ zmienne zdefiniowane przez użytkownika dla daty startu i daty zakończenia

W tym przykładzie zmienne zdefiniowane przez użytkownika służą jako argumenty dla daty startu i daty zakończenia.

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. Określ funkcje systemu skalarnego dla daty startu i daty zakończenia

Ten przykład wykorzystuje funkcje systemu skalarnego jako argumenty dla daty startu i daty zakończenia.

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

D. Określ podzapytania skalarne i funkcje skalarne dla daty startu i daty zakończenia

Ten przykład wykorzystuje podzapytania skalarne i funkcje skalarne jako argumenty dla daty startu i daty zakończenia.

USE AdventureWorks2022;
GO

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

E. Określ stałe dla daty startu i daty zakończenia

W tym przykładzie używa stałych znaków jako argumentów dla daty startu i daty zakończenia.

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

F. Określ wyrażenia liczbowe i funkcje systemu skalarnego dla daty końcowej

W tym przykładzie używa wyrażenia liczbowego , (GETDATE() + 1), oraz funkcji GETDATE systemu skalarnego i SYSDATETIME, jako argumentów dla daty końcowej.

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. Określ funkcje rankingu dla daty startowej

Ten przykład wykorzystuje funkcję rankingu jako argument dla daty początkowej.

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. Określ funkcję okna agregującego dla daty startowej

Ten przykład wykorzystuje funkcję okna agregującego jako argument dla daty startowej.

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

I. Znajdź różnicę między datą startową a datą końcową jako łańcuchy części daty

-- 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;

Oto zestaw wyników.

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

Przykłady: Azure Synapse Analytics and Analytics Platform System (PDW)

Przykłady te wykorzystują różne typy wyrażeń jako argumenty dla parametrów daty startu i daty zakończenia .

J. Określ kolumny dla daty startu i daty zakończenia

Ten przykład oblicza liczbę granic dni przeciętych między datami w dwóch kolumnach tabeli.

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

K. Określ podzapytania skalarne i funkcje skalarne dla daty startu i daty zakończenia

Ten przykład wykorzystuje podzapytania skalarne i funkcje skalarne jako argumenty dla daty startu i daty zakończenia.

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

L. Określ stałe dla daty startu i daty zakończenia

W tym przykładzie używa stałych znaków jako argumentów dla daty startu i daty zakończenia.

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

M. Określ funkcje rankingu dla daty startowej

Ten przykład wykorzystuje funkcję rankingu jako argument dla daty początkowej.

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

N. Określ funkcję okna agregującego dla daty startowej

Ten przykład wykorzystuje funkcję okna agregującego jako argument dla daty startowej.

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