DATEDIFF (Transact-SQL)
Viene restituito il conteggio (intero con segno) dei limiti datepart specificati che si sovrappongono tra startdate e enddate specificati.
Per una panoramica di tutti i tipi di dati e delle funzioni di data e ora Transact-SQL, vedere Funzioni e tipi di dati di data e ora (Transact-SQL). Per informazioni ed esempi comuni ai tipi di dati e alle funzioni di data e ora, vedere Utilizzo di dati relativi a data e ora.
Sintassi
DATEDIFF (datepart ,startdate ,enddate )
Argomenti
datepart
Parte di startdate ed enddate che specifica il tipo di limite sovrapposto. Nella tabella seguente vengono elencati tutti gli argomenti di datepart validi. Variabili definite dall'utente equivalenti non sono valide.datepart
Abbreviazioni
year
yy, yyyy
quarter
qq, q
month
mm, m
dayofyear
dy, y
day
dd, d
week
wk, ww
hour
hh
minute
mi, n
second
ss, s
millisecond
ms
microsecond
mcs
nanosecond
ns
startdate
Espressione che può essere risolta in un valore di tipo time, date, smalldatetime, datetime, datetime2 o datetimeoffset. I valori di tipo date possono essere costituiti da un'espressione, da un'espressione di colonna, da una variabile definita dall'utente o da un valore letterale stringa. Un valore startdate viene sottratto da un valore enddate.Per evitare ambiguità, esprimere gli anni nel formato a quattro cifre. Per informazioni sul formato di anno a due cifre, vedere Opzione two digit year cutoff.
enddate
Vedere startdate.
Tipo restituito
int
Valore restituito
- Ogni valore datepart e le relative abbreviazioni restituiscono lo stesso valore.
Se il valore restituito non è compreso nell'intervallo per int (da -2.147.483.648 a +2.147.483.647), viene restituito un errore. Per millisecond, la differenza massima tra startdate ed enddate è di 24 giorni, 20 ore, 31 minuti e 23.647 secondi. Per second, la differenza massima è 68 anni.
Se a startdate e a enddate è assegnato solo un valore di ora e il valore datepart non è un datepart di ora, viene restituito 0.
Un componente differenza di fuso orario di startdate o endate non è utilizzato nel calcolo del valore restituito.
Il valore smalldatetime garantisce la precisione solo a livello di minuti. Quando viene utilizzato un valore smalldatetime per startdate o enddate, nel valore restituito i secondi e i millisecondi vengono sempre impostati su 0.
Se a una variabile di tipo data viene assegnato solo un valore di tipo data, il valore della parte mancante della data viene impostato sul valore predefinito: 1900-01-01. Se a una variabile di tipo ora viene assegnato solo un valore di tipo data, il valore della parte mancante dell'ora viene impostato sul valore predefinito: 00-00-00. Se a un valore startdate o enddate viene assegnata rispettivamente solo la parte dell'ora e la parte della data, le parti mancanti vengono impostate sui valori predefiniti.
Se i valori startdate ed enddate sono di tipi data diversi e uno di questi comprende un numero maggiore di parti di ora o offre una precisione in secondi frazionari maggiore, le parti mancanti dell'altro valore vengono impostate su 0.
Limiti di datepart
Le istruzioni seguenti comprendono lo stesso valore startdate e lo stesso valore endate. Queste date sono adiacenti e differiscono di 0,0000001 secondi. La differenza tra il valore startdate e il valore endate in ciascuna istruzione si sovrappone a un limite di calendario o di ora del rispettivo valore datepart. Ciascuna istruzione restituisce 1. Se per questo esempio vengono utilizzati anni diversi e se startdate ed endate fanno parte della stessa settimana di calendario, il valore restituito per week è 0.
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(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');
Osservazioni
La funzione DATEDIFF può essere utilizzata in un elenco di selezione e nelle clausole WHERE, HAVING, GROUP BY e ORDER BY. In SQL Server 2008 DATEDIFF consente di eseguire il cast in modo implicito di valori letterali stringa come i tipi datetime2. Quando si utilizza DATEDIFF con DATEADD, evitare cast impliciti di valori letterali stringa. Per ulteriori informazioni, vedere DATEADD (Transact-SQL).
Esempi
Negli esempi seguenti sono utilizzati tipi diversi di espressioni come argomenti per i parametri startdate e enddate.
A. Indicazione di colonne per startdate ed enddate
Nell'esempio seguente viene calcolato il numero di limiti di giorno che si sovrappongono tra le date di due colonne in una tabella.
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;
-- Returns: 1
B. Indicazione di variabili definite dall'utente per startdate ed enddate
Nell'esempio seguente vengono utilizzate variabili definite dall'utente come argomenti per startdate ed enddate.
DECLARE @startdate datetime2 = '2007-05-05 12:10:09.3312722';
DECLARE @enddate datetime2 = '2007-05-04 12:10:09.3312722';
SELECT DATEDIFF(day, @startdate, @enddate);
C. Indicazione di funzioni di sistema scalari per startdate ed enddate
Nell'esempio seguente vengono utilizzate funzioni di sistema scalari come argomenti per startdate ed enddate.
SELECT DATEDIFF(millisecond, GETDATE(), SYSDATETIME());
C. Indicazione di sottoquery scalari e di funzioni scalari per startdate ed enddate
Nell'esempio seguente vengono utilizzate sottoquery scalari e funzioni scalari come argomenti per startdate ed enddate.
USE AdventureWorks;
GO
SELECT DATEDIFF(day,(SELECT MIN(OrderDate) FROM Sales.SalesOrderHeader),
(SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader));
E. Indicazione di costanti per startdate ed enddate
Nell'esempio seguente vengono utilizzate costanti di tipo carattere come argomenti per startdate ed enddate.
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635'
, '2007-05-08 09:53:01.0376635');
F. Indicazione di espressioni numeriche e funzioni di sistema scalari per enddate
Nell'esempio seguente vengono utilizzate una funzione numerica, (GETDATE ()+ 1), e funzioni di sistema scalari, GETDATE e SYSDATETIME, come argomenti per enddate.
[!NOTA]
SYSDATETIME, SYSUTCDATETIME e SYSDATETIMEOFFSET non possono far parte di un'espressione aritmetica.
USE AdventureWorks;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', GETDATE()+ 1)
AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
USE AdventureWorks;
GO
SELECT DATEDIFF(day, '2007-05-07 09:53:01.0376635', DATEADD(day,1,SYSDATETIME())) AS NumberOfDays
FROM Sales.SalesOrderHeader;
GO
G. Indicazione di funzioni di rango per startdate
Nell'esempio seguente è utilizzata una funzione di rango come argomento per startdate.
USE AdventureWorks;
GO
SELECT c.FirstName, c.LastName
,DATEDIFF(day,ROW_NUMBER() OVER (ORDER BY
a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s
INNER JOIN Person.Contact c
ON s.SalesPersonID = c.ContactID
INNER JOIN Person.Address a
ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
H. Indicazione di una funzione finestra di aggregazione per startdate
Nell'esempio seguente è utilizzata una funzione finestra di aggregazione come argomento per un parametro startdate.
USE AdventureWorks;
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 sod
INNER JOIN Sales.SalesOrderHeader soh
ON sod.SalesOrderID = soh.SalesOrderID
WHERE soh.SalesOrderID IN(43659,58918);
GO