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. DATEADD
tronca 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
, day
e 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
second
e un valore numerico compreso tra -30 e +29,DATEADD
non apporta modifiche.Per un valore datepart di
second
e 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
DATEADD
non 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
, microsecond
o 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