T-SQL datetime arrotondato al minuto e alle ore più vicine con l'utilizzo delle funzioni


113

In SQL Server 2008, vorrei ottenere la colonna datetime arrotondata all'ora più vicina e al minuto più vicino preferibilmente con le funzioni esistenti nel 2008.

Per questo valore di colonna 2007-09-22 15:07:38.850, l'output sarà simile a:

2007-09-22 15:08 -- nearest minute
2007-09-22 15    -- nearest hour

6
L'esempio del minuto più vicino non dovrebbe essere 15:08? Perché i secondi in un minuto sono 60 ...
OMG Ponies

Non hai intenzionalmente corretto quell'errore quando hai modificato la sua domanda in modo da poter fare quel commento?
Mr mercoledì

@MrWed Wednesday Ti rendi conto che ci sono più di 10 minuti tra la modifica e quel commento. Immagino che il pensiero sia avvenuto in seguito.
lc.

Risposte:


208
declare @dt datetime

set @dt = '09-22-2007 15:07:38.850'

select dateadd(mi, datediff(mi, 0, @dt), 0)
select dateadd(hour, datediff(hour, 0, @dt), 0)

sarà di ritorno

2007-09-22 15:07:00.000
2007-09-22 15:00:00.000

Quanto sopra tronca solo i secondi ei minuti, producendo i risultati richiesti nella domanda. Come ha sottolineato @OMG Ponies, se vuoi arrotondare per eccesso / per difetto, puoi aggiungere rispettivamente mezzo minuto o mezz'ora, quindi troncare:

select dateadd(mi, datediff(mi, 0, dateadd(s, 30, @dt)), 0)
select dateadd(hour, datediff(hour, 0, dateadd(mi, 30, @dt)), 0)

e otterrai:

2007-09-22 15:08:00.000
2007-09-22 15:00:00.000

Prima che il tipo di dati data fosse aggiunto in SQL Server 2008, avrei utilizzato il metodo sopra per troncare la parte dell'ora da un datetime per ottenere solo la data. L'idea è di determinare il numero di giorni tra il datetime in questione e un punto fisso nel tempo ( 0, che implicitamente esegue il cast su 1900-01-01 00:00:00.000):

declare @days int
set @days = datediff(day, 0, @dt)

e quindi aggiungi quel numero di giorni al punto temporale fisso, che ti dà la data originale con l'ora impostata su 00:00:00.000:

select dateadd(day, @days, 0)

o più succintamente:

select dateadd(day, datediff(day, 0, @dt), 0)

Utilizzando un datepart diversa (ad esempio hour, mi) funzionerà di conseguenza.


2
Dubito che qualcun altro si imbatterà in questo, ma se stai cercando di arrotondare al secondo più vicino e aggiungendo 500 millisecondi vorrai fare datiff (secondo, '1/1/2000', .... vs datiff (secondo, 0 .... poiché riceverai un errore di overflow. i secondi da 0 sono troppo grandi, immagino.
Eric Twilegar,

"Aggiungi il numero di ore dal 1 gennaio 1900 al 1 gennaio 1900": l'ho riscontrato in Java / SQL, dove sembra brutto. Nel mio caso avrebbe dovuto essere fatto sul lato Java.
Corwin Newall

Per i calcoli con datetimeoffset, ho dovuto sostituire 0con TODATETIMEOFFSET('1900-01-01 00:00:00', 0)per evitare di forzare il fuso orario locale sul risultato.
krlmlr

26

"Arrotondato" per difetto come nel tuo esempio. Ciò restituirà un valore varchar della data.

DECLARE @date As DateTime2
SET @date = '2007-09-22 15:07:38.850'

SELECT CONVERT(VARCHAR(16), @date, 120) --2007-09-22 15:07
SELECT CONVERT(VARCHAR(13), @date, 120) --2007-09-22 15

Convertire il varchar in datetime potrebbe fare (per ora):CONVERT(datetime, CONVERT(VARCHAR(13), @date, 120)+':00:00')
Decula

10

Mi rendo conto che questa domanda è antica e c'è una risposta accettata e una alternativa. Mi rendo anche conto che la mia risposta risponderà solo a metà della domanda, ma per chiunque desideri arrotondare al minuto più vicino e avere ancora un valore compatibile con data e ora utilizzando solo una singola funzione :

CAST(YourValueHere as smalldatetime);

Per ore o secondi, usa la risposta di Jeff Ogata (la risposta accettata) sopra.


1
Ottima risposta, ho verificato che arrotonda e non si limita a troncare. Per chiunque altro smalldatetime
stia

Questa è l'opzione migliore se hai bisogno di correggere alcuni dati nella tua tabella che richiedono solo un timeout al minuto.
Crittografia

-1

Select convert(char(8), DATEADD(MINUTE, DATEDIFF(MINUTE, 0, getdate), 0), 108) as Time

arrotonderà i secondi a 00


Molto lento e non si arrotonda come richiesto dall'OP, ma si arrotonda per difetto, cosa che non ha richiesto. (Disclaimer - Non ti ho votato per
difetto
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.