DATEDIFF (Transact-SQL)

gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)SQL-databas i Microsoft Fabric

Denna funktion returnerar räkningen (som ett signerat heltalsvärde) av de angivna datumdelsgränserna som korsats mellan det angivna start- och slutdatumet.

Se DATEDIFF_BIG för en funktion som hanterar större skillnader mellan start- och slutdatumvärden . Se Datatyper och funktioner för datum och tid för en översikt över alla Transact-SQL datatyper och funktioner för datum och tid.

Transact-SQL syntaxkonventioner

Syntax

DATEDIFF ( datepart , startdate , enddate )

Arguments

datepart

Specificerar vilka enheter som DATEDIFF rapporterar skillnaden mellan startdatum och slutdatum. Vanligt använda datepart-enheter inkluderar month eller second.

Datepart-värdet kan inte specificeras i en variabel, inte heller som en citerad sträng som 'month'.

Följande tabell listar alla giltiga datumdelsvärden . DATEDIFF accepterar antingen det fullständiga namnet på datumdelen eller någon angiven förkortning av det fullständiga namnet.

Datumpartsnamn datepart-förkortning
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

Varje specifikt datumdelsnamn och förkortningar för det datumdelens namn ger samma värde.

startdate

Ett uttryck som kan matcha något av följande värden:

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

Använd fyrsiffriga år för att undvika oklarhet. Se Serverkonfiguration: tvåsiffrig årsgräns för information om tvåsiffriga årsvärden.

enddate

Se startdate.

Returtyper

int

Returvärde

Int-skillnaden mellan startdatum och slutdatum, uttryckt i gränsen satt av datumdelen.

Till exempel SELECT DATEDIFF(day, '2036-03-01', '2036-02-28'); avkastning -2, vilket antyder att 2036 måste vara ett skottår. Detta fall innebär att om vi börjar vid startdatum2036-03-01 och sedan räknar -2 dagar, når vi slutdatumet för 2036-02-28.

För ett returvärde utanför intervallet för int (-2 147 483 648 till +2 147 483 647), DATEDIFF returnerar ett fel. För millisecond, är den maximala skillnaden mellan startdatum och slutdatum 24 dagar, 20 timmar, 31 minuter och 23,647 sekunder. För second, är den maximala skillnaden 68 år, 19 dagar, 3 timmar, 14 minuter och 7 sekunder.

Om startdatum och slutdatum båda endast tilldelas ett tidsvärde, och datumdelen inte är en tidsdatumdel,DATEDIFF returnerar 0.

DATEDIFF använder tidszonsförskjutningskomponenten startdatum eller slutdatum för att beräkna returvärdet.

Eftersom smalldatetime endast är exakt till minut, sätts sekunder och millisekunder alltid till 0 i returvärdet när start- eller slutdatum har ett smalldatetime-värde .

Om endast ett tidsvärde tilldelas till en variabel DATEDIFF för datumdatatyp anger du värdet för den saknade datumdelen till standardvärdet: 1900-01-01. Om endast ett datumvärde tilldelas till en variabel av en tids- eller datumdatatyp anger DATEDIFF du värdet för den saknade tidsdelen till standardvärdet: 00:00:00. Om antingen startdate eller enddate bara har en tidsdel och den andra endast en datumdel, DATEDIFF anger du de saknade tids- och datumdelarna till standardvärdena.

Om startdatum och slutdatum har olika datumdatatyper, och den ena har fler tidsdelar eller bråkdelar av sekunder precision än den andra, DATEDIFF sätter de saknade delarna i den andra till 0.

Datumdelsgränser

Följande instruktioner har samma startdatum och samma enddate-värden . Dessa datum ligger intill varandra och skiljer sig i tid med hundra nanosekunder (0,0000001 sekund). Skillnaden mellan startdate och enddate i varje -instruktion korsar en kalender eller tidsgräns för dess datepart. Varje påstående returnerar 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');

Om startdatum och slutdatum har olika årsvärden, men de har samma kalenderveckor, DATEDIFF returnerar 0 för datumdelenweek.

Anmärkningar

Använd DATEDIFF i SELECT <list>, WHERE, HAVING, , GROUP BYoch ORDER BY satserna.

DATEDIFF omvandlar implicit strängliteraler som en datetime2-typ . Med andra ord DATEDIFF stöder inte formatet YDM när datumet passeras som en sträng. Du måste uttryckligen kasta strängen till en datetime- eller smalldatetime-typ för att använda formatet YDM .

Att ange SET DATEFIRST har ingen effekt på DATEDIFF. DATEDIFF använder alltid söndag som den första dagen i veckan för att säkerställa att funktionen fungerar på ett deterministiskt sätt.

DATEDIFF kan översvämma med en precision på minute eller högre, om skillnaden mellan slutdatum och startdatum ger ett värde som ligger utanför intervallet för int.

Examples

Kodexemplen i den här artikeln använder AdventureWorks2025- eller AdventureWorksDW2025-exempeldatabasen, som du kan ladda ned från startsidan Microsoft SQL Server Samples och Community Projects.

Dessa exempel använder olika typer av uttryck som argument för start- och slutdatumparametrarna .

A. Ange kolumner för startdatum och slutdatum

Detta exempel beräknar antalet daggränser som korsas mellan datum i två kolumner i en tabell.

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;

Här är resultatet.

Duration
--------
1

B. Ange användardefinierade variabler för startdatum och slutdatum

I detta exempel fungerar användardefinierade variabler som argument för startdatum och slutdatum.

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. Specificera skalärsystemfunktioner för startdatum och slutdatum

Detta exempel använder skalära systemfunktioner som argument för start- och slutdatum.

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

D. Specificera skalära subförfrågningar och skalära funktioner för start- och slutdatum

Detta exempel använder skalära underfrågor och skalära funktioner som argument för start- och slutdatum.

USE AdventureWorks2022;
GO

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

E. Ange konstanter för startdatum och slutdatum

Detta exempel använder teckenkonstanter som argument för start- och slutdatum.

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

F. Specificera numeriska uttryck och skalärsystemfunktioner för slutdatum

Detta exempel använder ett numeriskt uttryck, (GETDATE() + 1), och skalärsystemfunktionerna GETDATE och SYSDATETIME, som argument för slutdatum.

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. Ange rankningsfunktioner för startdatum

Detta exempel använder en rangordningsfunktion som argument för startdatum.

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. Ange en aggregerad fönsterfunktion för startdatum

Detta exempel använder en aggregerad fönsterfunktion som argument för startdatum.

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. Hitta skillnaden mellan startdatum och slutdatum när datumdelade strängar

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

Här är resultatet.

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

Exempel: Azure Synapse Analytics and Analytics Platform System (PDW)

Dessa exempel använder olika typer av uttryck som argument för start- och slutdatumparametrarna .

J. Ange kolumner för startdatum och slutdatum

Detta exempel beräknar antalet daggränser som korsas mellan datum i två kolumner i en tabell.

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. Specificera skalära subförfrågningar och skalära funktioner för start- och slutdatum

Detta exempel använder skalära underfrågor och skalära funktioner som argument för start- och slutdatum.

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

L. Ange konstanter för startdatum och slutdatum

Detta exempel använder teckenkonstanter som argument för start- och slutdatum.

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

M. Ange rankningsfunktioner för startdatum

Detta exempel använder en rangordningsfunktion som argument för startdatum.

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

N. Ange en aggregerad fönsterfunktion för startdatum

Detta exempel använder en aggregerad fönsterfunktion som argument för startdatum.

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