Condividi tramite


DATEADD (Transact-SQL)

Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Piattaforma di strumenti analitici (PDW) Endpoint di analisi SQL in Microsoft Fabric Warehouse in Microsoft Fabric

Questa funzione aggiunge un valore number (un valore integer con segno) a un parametro datepart di una data di input e restituisce un valore date/time modificato. Ad esempio, è possibile usare questa funzione per trovare la data che corrisponde a 7.000 minuti da oggi: number = 7000, datepart = minute, date = today.

Vedere Funzioni e tipi di dati di data e ora per una panoramica di tutti i tipi di dati e le funzioni di data e ora Transact-SQL.

Convenzioni relative alla sintassi Transact-SQL

Sintassi

DATEADD (datepart , number , date )

Argomenti

datepart

Parte della data a cui DATEADD aggiunge un numero int. Questa tabella elenca tutti gli argomenti validi per datepart.

Nota

DATEADD non accetta equivalenti di variabili definite dall'utente come argomenti di datepart.

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

Espressione che può essere risolta in un tipo int aggiunto da DATEADD a un elemento datepart di date. DATEADD accetta valori di variabili definite dall'utente per number. DATEADDtronca un valore numerico specificato con una frazione decimale. Non arrotonda il valore numerico in questa situazione.

date

Espressione che può risolversi in uno dei valori seguenti:

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

Per date, DATEADD accetta un'espressione di colonna, un'espressione, un valore letterale stringa o una variabile definita dall'utente. Un valore stringa deve risolversi in un elemento datetime. Per evitare problemi di ambiguità, esprimere gli anni nel formato a quattro cifre. Per informazioni sugli anni a due cifre, vedere Configurare il cutoff dell'anno a due cifre (opzione di configurazione del server).

Tipi restituiti

Il tipo di dati del valore restituito per questo metodo è dinamico. Il tipo restituito dipende dall'argomento specificato per date. Se il valore per date è una data letterale stringa, DATEADD restituisce un valore datetime. Se viene fornito un altro tipo di dati di input valido per date, DATEADD restituisce lo stesso tipo di dati. DATEADD genera un errore se la scala dei secondi del valore letterale stringa supera tre posizioni decimali (.nnn) o se il valore letterale stringa contiene la parte relativa alla differenza di fuso orario.

Valore restituito

Argomento datepart

dayofyear, daye weekday restituiscono lo stesso valore.

Ogni elemento datepart e le relative abbreviazioni restituiscono lo stesso valore.

Se si verificano le condizioni seguenti:

  • datepart è month
  • il mese di date ha più giorni del mese restituito
  • il giorno della data non esiste nel mese restituito

DATEADD restituisce l'ultimo giorno del mese restituito. Ad esempio, settembre ha 30 (trenta) giorni; pertanto, queste istruzioni restituiscono 2024-09-30 00:00:00.000:

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

Argomento number

L'argomento number non può superare l'intervallo di int. Nelle istruzioni seguenti, l'argomento per number supera l'intervallo di int di 1. Queste istruzioni restituiscono entrambi il messaggio di errore seguente: Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int.

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

Argomento date

DATEADD non accetta un argomento date incrementato a un valore non compreso nell'intervallo del relativo tipo di dati. Nelle istruzioni seguenti il valore number aggiunto al valore date supera l'intervallo del tipo di dati date. DATEADD restituisce il messaggio di errore seguente: Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow.

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

Restituisce valori per una data smalldatetime e una datepart di secondi secondi o frazionari

La seconda parte di un valore smalldatetime è sempre 00. Per un valore date smalldatetime, si applica quanto segue:

  • Per un valore datepart di seconde un valore numerico compreso tra -30 e +29, DATEADD non apporta modifiche.

  • Per un valore datepart di seconde un valore numerico minore di -30 o più di +29, DATEADD esegue l'addizione a partire da un minuto.

  • Per un valore datepart di millisecond e un valore numerico compreso tra -30001 e +29998, DATEADD non apporta modifiche.

  • Per un valore datepart di millisecond e un valore numerico minore di -30001 o più di +29998, DATEADD esegue l'addizione a partire da un minuto.

Osservazioni:

Usare DATEADD nelle clausole seguenti:

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

Precisione in secondi frazionari

DATEADDnon consente l'aggiunta di un valore datepart di microsecond o nanosecond per i tipi di dati date smalldatetime, date e datetime.

I millisecondi hanno una scala di 3 (.123), i microsecondi hanno una scala di 6 (.123456) e i nanosecondi hanno una scala di 9 (.123456789). I tipi di dati time, datetime2 e datetimeoffset hanno una scala massima di 7 (.1234567). Per un valore datepart di nanosecond, il numero deve essere 100 prima dell'aumento dei secondi frazionari della data . Un numero compreso tra 1 e 49 arrotonda fino a 0 e un numero compreso tra 50 e 99 arrotonda fino a 100.

Queste istruzioni aggiungono una datepart di millisecond, microsecondo nanosecond.

DECLARE @datetime2 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);

Il set di risultati è il seguente.

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

Differenza di fuso orario

DATEADD non consente l'aggiunta per la differenza di fuso orario.

Esempi

R. Incrementare datepart per un intervallo di 1

Ognuna di queste istruzioni incrementa il valore datepart a intervalli di una unità:

DECLARE @datetime2 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);

Il set di risultati è il seguente.

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. Incrementare più di un livello di datepart in un'istruzione

Ognuna di queste istruzioni incrementa datepart di un valore number abbastanza grande da incrementare anche l'argomento datepart di livello immediatamente più alto di date:

DECLARE @datetime2 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. Utilizzare espressioni come argomenti per i parametri number e date

In questi esempi vengono usati tipi diversi di espressioni come argomenti per i parametri number e date. Gli esempi usano il database AdventureWorks.

Specificare una colonna per il parametro date

In questo esempio vengono aggiunti 2 (due) giorni a ogni valore nella colonna OrderDate per derivare una nuova colonna denominata PromisedShipDate:

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

Ecco un set di risultati parziale:

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

Specificare variabili definite dall'utente per i parametri number e date

In questo esempio vengono specificate variabili definite dall'utente come argomenti per i parametri number e date:

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

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

Il set di risultati è il seguente.

2000-12-31 01:01:01.110

Specificare una funzione di sistema scalare per il parametro date

Questo esempio specifica SYSDATETIME per date. Il valore esatto restituito dipende dal giorno e dall'ora di esecuzione dell'istruzione:

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

Il set di risultati è il seguente.

2024-04-25 14:29:59.6727944

Specificare sottoquery scalari e funzioni scalari per i parametri number e date

In questo esempio vengono usate sottoquery scalari, MAX(ModifiedDate), come argomenti per number e date. (SELECT TOP 1 BusinessEntityID FROM Person.Person) funge da argomento fittizio perché il parametro number illustri come selezionare un argomento number da un elenco di valori.

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

Specificare espressioni numeriche e funzioni di sistema scalari per i parametri number e date

Questo esempio usa un'espressione numerica (), operatori unari (-), un operatore aritmetico (/) e funzioni di sistema scalari (SYSDATETIME) come argomenti per number e date. -(10 / 2)

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

Specificare le funzioni di classificazione come numero

Questo esempio usa una funzione di rango come argomento per number.

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;

Specificare una funzione finestra di aggregazione per il parametro number

Questo esempio usa una funzione finestra di aggregazione come argomento per un parametro number.

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