Dela via


DATEADD (Transact-SQL)

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

Den här funktionen lägger till ett tal (ett signerat heltal) till en datumdel av ett indatadatum och returnerar ett ändrat datum/tid-värde. Du kan till exempel använda den här funktionen för att hitta det datum som är 7 000 minuter från idag: tal = 7 000, datepart = minut, datum = idag.

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

DATEADD (datepart , number , date )

Arguments

datepart

Den del av datumet som DATEADD lägger till ett int-nummer.

I den här tabellen visas alla giltiga datepart-argument . DATEADD accepterar inte användardefinierade variabelmotsvarigheter för datepart-argumenten .

datepart Abbreviations
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

number

Ett uttryck som kan matcha till en int som DATEADD lägger till i en datumdel av datumet. DATEADD accepterar användardefinierade variabelvärden för tal. DATEADD trunkerar ett angivet talvärde som har ett decimaltal. Det avrundar inte talvärdet i den här situationen.

Note

I SQL Server 2025 (17.x) Preview, Azure SQL Database, Azure SQL Managed Instance och SQL Database i Microsoft Fabric Preview kan antalet uttryckas som en storint. Den här funktionen är en förhandsversion.

date

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

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

För datumDATEADD accepterar ett kolumnuttryck, uttryck, strängliteral eller användardefinierad variabel. Ett strängliteralt värde måste matchas till en datetime. Använd fyrsiffriga år för att undvika tvetydighetsproblem. Mer information om tvåsiffriga år finns i Serverkonfiguration: tvåsiffrig årsgränsen .

Returtyper

Datatypen returneringsvärde för den här metoden är dynamisk. Returtypen beror på argumentet som angetts för date. Om värdet för date är ett strängliteralt datum DATEADD returnerar ett datetime-värde . Om en annan giltig indatatyp anges för dateDATEADD returnerar samma datatyp. DATEADD genererar ett fel om strängliterala sekundersskalan överskrider tre decimalplaceringar (.nnn) eller om strängliteralen innehåller tidszonens förskjutningsdel.

Returvärde

datepart-argument

dayofyear, dayoch weekday returnerar samma värde.

Varje datumdel och dess förkortningar returnerar samma värde.

Om följande är sant:

  • datepart är month
  • datummånaden har fler dagar än returmånaden
  • datumdagen finns inte i returmånaden

DATEADD Returnerar sedan den sista dagen i returmånaden. September har till exempel 30 (trettio) dagar. Dessa påståenden returnerar 2024-09-30 00:00:00.000därför :

SELECT DATEADD(month, 1, '20240830');
SELECT DATEADD(month, 1, '2024-08-31');

talargument

Talargumentet får inte överskrida int-intervallet. I följande instruktioner överskrider argumentet för tal intervallet för int med 1.

SELECT DATEADD(year, 2147483648, '20240731');
SELECT DATEADD(year, -2147483649, '20240731');

Båda dessa instruktioner returnerar följande felmeddelande:

Msg 8115, Level 16, State 2, Line 1
Arithmetic overflow error converting expression to data type int.

Note

I SQL Server 2025 (17.x) Preview, Azure SQL Database, Azure SQL Managed Instance och SQL Database i Microsoft Fabric Preview kan antalet uttryckas som en storint. Den här funktionen är en förhandsversion.

datumargument

DATEADD accepterar inte ett datumargument som har ökats till ett värde utanför datatypens intervall. I följande instruktioner överskrider det talvärde som läggs till i datumvärdet intervallet för datumdatatypen .

SELECT DATEADD(year, 2147483647, '20240731');
SELECT DATEADD(year, -2147483647, '20240731');

DATEADD returnerar följande felmeddelande:

Msg 517, Level 16, State 1
Line 1 Adding a value to a 'datetime' column caused overflow.

Returnera värden för ett smalldatetime-datum och en sekund eller en bråkdels sekund datepart

Sekunddelen av ett smalldatetime-värde är alltid 00. För ett smalldatetime-datumvärde gäller följande:

  • För en datepart av secondoch ett talvärde mellan -30 och +29 DATEADD gör inga ändringar.

  • För en datepart av second, och ett talvärde som är mindre än -30, eller mer än +29, DATEADD utför tillägget från och med en minut.

  • För en datepart av millisecond och ett talvärde mellan -30001 och +29998 DATEADD gör du inga ändringar.

  • För en datepart av millisecond och ett talvärde som är mindre än -30001, eller mer än +29998, DATEADD utför tillägget från och med en minut.

Remarks

Använd DATEADD i följande satser:

  • GROUP BY
  • HAVING
  • ORDER BY
  • SELECT <list>
  • WHERE

Precision för bråksekunder

DATEADD tillåter inte tillägg för en datepart av microsecond eller nanosecond för datumdatatypersmalldatetime, date och datetime.

Millisekunder har en skala på 3 (.123), mikrosekunder har en skala på 6 (.123456) och nanosekunder har en skala på 9 (.123456789). Datatyperna tid, datetime2 och datetimeoffset har en maximal skala på 7 (.1234567). För en datepart av nanosecondmåste talet vara 100 innan bråksekunderna för datumökningen . Ett tal mellan 1 och 49 avrundar ned till 0 och ett tal från 50 till 99 avrundar upp till 100.

Dessa instruktioner lägger till en datepart av millisecond, microsecondeller nanosecond.

DECLARE @datetime2 AS DATETIME2 = '2024-01-01 13:10:10.1111111';

SELECT '1 millisecond', DATEADD(millisecond, 1, @datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond, 2, @datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond, 1, @datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond, 2, @datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond, 49, @datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond, 50, @datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond, 150, @datetime2);

Här är resultatet.

1 millisecond     2024-01-01 13:10:10.1121111
2 milliseconds    2024-01-01 13:10:10.1131111
1 microsecond     2024-01-01 13:10:10.1111121
2 microseconds    2024-01-01 13:10:10.1111131
49 nanoseconds    2024-01-01 13:10:10.1111111
50 nanoseconds    2024-01-01 13:10:10.1111112
150 nanoseconds   2024-01-01 13:10:10.1111113

Tidszonsförskjutning

DATEADD tillåter inte tillägg för tidszonsförskjutning.

Examples

A. Inkrement datepart med ett intervall på 1

Var och en av dessa instruktioner ökar datepart med ett intervall på 1:

DECLARE @datetime2 AS DATETIME2 = '2024-01-01 13:10:10.1111111';

SELECT 'year', DATEADD(year, 1, @datetime2)
UNION ALL
SELECT 'quarter', DATEADD(quarter, 1, @datetime2)
UNION ALL
SELECT 'month', DATEADD(month, 1, @datetime2)
UNION ALL
SELECT 'dayofyear', DATEADD(dayofyear, 1, @datetime2)
UNION ALL
SELECT 'day', DATEADD(day, 1, @datetime2)
UNION ALL
SELECT 'week', DATEADD(week, 1, @datetime2)
UNION ALL
SELECT 'weekday', DATEADD(weekday, 1, @datetime2)
UNION ALL
SELECT 'hour', DATEADD(hour, 1, @datetime2)
UNION ALL
SELECT 'minute', DATEADD(minute, 1, @datetime2)
UNION ALL
SELECT 'second', DATEADD(second, 1, @datetime2)
UNION ALL
SELECT 'millisecond', DATEADD(millisecond, 1, @datetime2)
UNION ALL
SELECT 'microsecond', DATEADD(microsecond, 1, @datetime2)
UNION ALL
SELECT 'nanosecond', DATEADD(nanosecond, 1, @datetime2);

Här är resultatet.

year         2025-01-01 13:10:10.1111111
quarter      2024-04-01 13:10:10.1111111
month        2024-02-01 13:10:10.1111111
dayofyear    2024-01-02 13:10:10.1111111
day          2024-01-02 13:10:10.1111111
week         2024-01-08 13:10:10.1111111
weekday      2024-01-02 13:10:10.1111111
hour         2024-01-01 14:10:10.1111111
minute       2024-01-01 13:11:10.1111111
second       2024-01-01 13:10:11.1111111
millisecond  2024-01-01 13:10:10.1121111
microsecond  2024-01-01 13:10:10.1111121
nanosecond   2024-01-01 13:10:10.1111111

B. Öka mer än en nivå av datepart i en -instruktion

Var och en av dessa instruktioner ökar dateparten med ett tal som är tillräckligt stort för att ytterligare öka nästa högre datumdel av datumet:

DECLARE @datetime2 AS DATETIME2;

SET @datetime2 = '2024-01-01 01:01:01.1111111';

--Statement                                 Result
-------------------------------------------------------------------
SELECT DATEADD(quarter, 4, @datetime2);     --2025-01-01 01:01:01.1111111
SELECT DATEADD(month, 13, @datetime2);      --2025-02-01 01:01:01.1111111
SELECT DATEADD(dayofyear, 366, @datetime2); --2025-01-01 01:01:01.1111111
SELECT DATEADD(day, 366, @datetime2);       --2025-01-01 01:01:01.1111111
SELECT DATEADD(week, 5, @datetime2);        --2024-02-05 01:01:01.1111111
SELECT DATEADD(weekday, 31, @datetime2);    --2024-02-01 01:01:01.1111111
SELECT DATEADD(hour, 23, @datetime2);       --2024-01-02 00:01:01.1111111
SELECT DATEADD(minute, 59, @datetime2);     --2024-01-01 02:00:01.1111111
SELECT DATEADD(second, 59, @datetime2);     --2024-01-01 01:02:00.1111111
SELECT DATEADD(millisecond, 1, @datetime2); --2024-01-01 01:01:01.1121111

C. Använda uttryck som argument för parametrarna tal och datum

I de här exemplen används olika typer av uttryck som argument för tal - och datumparametrarna . I exemplen används databasen AdventureWorks.

Ange en kolumn som datum

Det här exemplet lägger till 2 (två) dagar till varje värde i OrderDate kolumnen för att härleda en ny kolumn med namnet PromisedShipDate:

SELECT SalesOrderID,
       OrderDate,
       DATEADD(day, 2, OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Här är en partiell resultatuppsättning:

SalesOrderID OrderDate               PromisedShipDate
------------ ----------------------- -----------------------
43659        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43660        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43661        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
...
43702        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43703        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43704        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43705        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43706        2005-07-03 00:00:00.000 2005-07-05 00:00:00.000
...
43711        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
43712        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
...
43740        2005-07-11 00:00:00.000 2005-07-13 00:00:00.000
43741        2005-07-12 00:00:00.000 2005-07-14 00:00:00.000

Ange användardefinierade variabler som tal och datum

I det här exemplet anges användardefinierade variabler som argument för tal och datum:

DECLARE
    @days AS INT = 365,
    @datetime AS DATETIME = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */

SELECT DATEADD(day, @days, @datetime);

Här är resultatet.

2000-12-31 01:01:01.110

Ange skalär systemfunktion som datum

Det här exemplet anger SYSDATETIME för datum. Det exakta värdet som returneras beror på dagen och tiden för instruktionskörningen:

SELECT DATEADD(month, 1, SYSDATETIME());

Här är resultatet.

2024-04-25 14:29:59.6727944

Ange skalära underfrågor och skalärfunktioner som tal och datum

I det här exemplet används skalära underfrågor, MAX(ModifiedDate), som argument för tal och datum. (SELECT TOP 1 BusinessEntityID FROM Person.Person) fungerar som ett artificiellt argument för talparametern för att visa hur du väljer ett talargument från en värdelista.

SELECT DATEADD(month,
    (SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person)
);

Ange numeriska uttryck och skalära systemfunktioner som tal och datum

I det här exemplet används ett numeriskt uttryck (-(10 / 2)), unary-operatorer (-), en aritmetikoperator (/) och skalära systemfunktioner (SYSDATETIME) som argument för tal och datum.

SELECT DATEADD(month, -(10 / 2), SYSDATETIME());

Ange rangordningsfunktioner som tal

I det här exemplet används en rangordningsfunktion som ett argument för tal.

SELECT p.FirstName,
       p.LastName,
       DATEADD(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;

Ange en mängdfönsterfunktion som tal

I det här exemplet används en mängdfönsterfunktion som argument för tal.

SELECT SalesOrderID,
       ProductID,
       OrderQty,
       DATEADD(day, SUM(OrderQty) OVER (PARTITION BY SalesOrderID), SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN (43659, 43664);
GO