Sdílet prostřednictvím


DATEDIFF (Transact-SQL)

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)databáze SQL v Microsoft Fabric

Tato funkce vrací počet (jako podepsanou celočíselnou hodnotu) zadaných hranic datepartu překročených mezi stanoveným datem začátku a date.

Viz DATEDIFF_BIG pro funkci, která zpracovává větší rozdíly mezi hodnotami startového akoncového data . Přehled všech datových typů a funkcí Transact-SQL datových typů a funkcí data a času najdete v tématu Datum a čas .

Transact-SQL konvence syntaxe

Syntaxe

DATEDIFF ( datepart , startdate , enddate )

Arguments

datepart

Specifikuje jednotky, které hlásí DATEDIFF rozdíl mezi datem začátku a koncem. Běžně používané jednotky datepart zahrnují month nebo second.

Hodnota datepart nemůže být specifikována ve proměnné ani jako uvozovkový řetězec jako 'month'.

Následující tabulka uvádí všechny platné hodnoty datepartů . DATEDIFF přijímá buď plný název datové části, nebo jakoukoli uvedenou zkratku celého jména.

název datové části zkratka 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

Každý konkrétní název datepart a zkratky pro daný název data vrátí stejnou hodnotu.

startdate

Výraz, který se dá přeložit na jednu z následujících hodnot:

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

Používejte čtyřciferné roky, abyste se vyhnuli nejasnosti. Viz Server configuration: dvouciferný roční cutoff pro informace o dvouciferných hodnotách roku.

enddate

Viz startdate.

Návratové typy

int

Návratová hodnota

Rozdíl mezidatem začátku a konce, vyjádřený hranicí stanovenou datem datepart.

Například vrací SELECT DATEDIFF(day, '2036-03-01', '2036-02-28');-2, což naznačuje, že rok 2036 musí být přestupný. Tento případ znamená, že pokud začneme od začátku2036-03-01 a pak počítáme -2 dny, dosáhneme koncového data2036-02-28.

Pro vrácenou hodnotu mimo rozsah pro int (-2 147 483 648 až +2 147 483 647) DATEDIFF vrátí chybu. Pro millisecond, maximální rozdíl mezi datem začátku a koncem je 24 dní, 20 hodin, 31 minut a 23,647 sekundy. Pro second, maximální rozdíl je 68 let, 19 dní, 3 hodiny, 14 minut a 7 sekund.

Pokud jsou obapřiřazeny počáteční a koncové datum pouze časové hodnoty a datová část není časová část, DATEDIFF vrátí 0.

DATEDIFF Používá komponentu časového posunu jako počáteční nebokoncové datum pro výpočet vrácené hodnoty.

Protože smalldatetime je přesný pouze na minutu, sekundy a milisekundy jsou vždy nastaveny na 0 návratovou hodnotu, když startdate nebo enddate mají hodnotu smalldatetime .

Pokud je k proměnné datového typu kalendářního data přiřazena pouze časová hodnota, DATEDIFF nastaví hodnotu chybějící části data na výchozí hodnotu: 1900-01-01. Pokud je k proměnné datového typu čas nebo datum přiřazena pouze hodnota data, DATEDIFF nastaví hodnotu chybějící časové části na výchozí hodnotu: 00:00:00. Pokud mají počáteční nebo koncové datum pouze časovou část a druhá pouze část data, DATEDIFF nastaví chybějící části času a data na výchozí hodnoty.

Pokud mají počáteční akoncové datum různé datové typy a jeden má více časových částí nebo zlomkové přesnosti než druhý, nastaví DATEDIFF chybějící části druhého na .0

Hranice datepart

Následující příkazy mají stejné počáteční datum a stejné hodnoty enddate . Tyto termíny jsou vedle sebe a liší se časem o sto nanosekund (0,0000001 sekundy). Rozdíl mezi počátečním a koncovým datem v každém příkazu překračuje jednu kalendářní nebo časovou hranici jeho části data. Každý příkaz vrací 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');

Pokud mají datum začátku a konec různé hodnoty roku, ale stejné hodnoty kalendářního týdne, DATEDIFF vrací se 0 pro částweek dat.

Poznámky

Použití DATEDIFF v SELECT <list>, WHERE, HAVING, GROUP BY, a větách ORDER BY .

DATEDIFF implicitně přetypuje řetězcové literály jako typ datetime2 . Jinými slovy, DATEDIFF nepodporuje formát YDM , když je datum předáno jako řetězec. Pro použití formátu musíte řetězec explicitně převést na typ datetime nebo YDM.

Určení SET DATEFIRST nemá žádný vliv na DATEDIFF. DATEDIFF vždy používá neděli jako první den v týdnu, aby se zajistilo, že funkce funguje deterministickým způsobem.

DATEDIFF může přetéct s přesností nebo minute vyšší, pokud rozdíl mezi koncovým astartovým datem vrátí hodnotu mimo rozsah pro int.

Examples

Ukázky kódu v tomto článku používají ukázkovou databázi AdventureWorks2025 nebo AdventureWorksDW2025, kterou si můžete stáhnout z domovské stránky Microsoft SQL Serveru pro ukázky a komunitní projekty .

Tyto příklady používají různé typy výrazů jako argumenty pro parametry startového akoncového data .

A. Zadejte sloupce pro počáteční a koncové datum

Tento příklad vypočítá počet hranic dnů překročených mezi daty ve dvou sloupcích tabulky.

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;

Tady je soubor výsledků.

Duration
--------
1

B. Specifikujte uživatelsky definované proměnné pro počáteční a koncové datum

V tomto příkladu slouží uživatelsky definované proměnné jako argumenty pro počáteční akoncové datum.

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. Specifikujte skalární systémové funkce pro počáteční a koncové datum

Tento příklad používá skalární systémové funkce jako argumenty pro počáteční akoncové datum.

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

D. Specifikujte skalární poddotazy a skalární funkce pro počáteční a koncové datum

Tento příklad používá skalární poddotazy a skalární funkce jako argumenty pro počáteční akoncové datum.

USE AdventureWorks2022;
GO

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

E. Specifikujte konstanty pro počáteční a koncové datum

Tento příklad používá znakové konstanty jako argumenty pro počáteční akoncové datum.

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

F. Specifikujte číselné výrazy a skalární systémové funkce pro koncové datum

Tento příklad používá číselný výraz , (GETDATE() + 1), a skalární systémové funkce GETDATE a , SYSDATETIMEjako argumenty pro koncové datum.

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. Specifikujte funkce pořadí pro počáteční datum

Tento příklad používá funkci hodnocení jako argument pro počáteční datum.

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. Zadejte agregovanou window funkci pro počáteční datum

Tento příklad používá agregovanou window funkci jako argument pro počáteční datum.

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. Najděte rozdíl mezi datem startu a koncovým datem jako řetězce částí data

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

Tady je soubor výsledků.

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

Příklady: Azure Synapse Analytics a Analytický platformový systém (PDW)

Tyto příklady používají různé typy výrazů jako argumenty pro parametry startového akoncového data .

J. Zadejte sloupce pro počáteční a koncové datum

Tento příklad vypočítá počet hranic dnů překročených mezi daty ve dvou sloupcích tabulky.

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. Specifikujte skalární poddotazy a skalární funkce pro počáteční a koncové datum

Tento příklad používá skalární poddotazy a skalární funkce jako argumenty pro počáteční akoncové datum.

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

L. Specifikujte konstanty pro počáteční a koncové datum

Tento příklad používá znakové konstanty jako argumenty pro počáteční akoncové datum.

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

M. Specifikujte funkce pořadí pro počáteční datum

Tento příklad používá funkci hodnocení jako argument pro počáteční datum.

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

N. Zadejte agregovanou window funkci pro počáteční datum

Tento příklad používá agregovanou window funkci jako argument pro počáteční datum.

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