Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come posso troncare un datetime in SQL Server?

Questo continua a raccogliere frequentemente voti aggiuntivi, anche diversi anni dopo, quindi devo aggiornarlo per le versioni moderne di Sql Server. Per Sql Server 2008 e versioni successive, è semplice:

cast(getDate() As Date)

Nota che gli ultimi tre paragrafi vicino alla parte inferiore si applicano ancora e spesso devi fare un passo indietro e trovare un modo per evitare l'ingessatura in primo luogo.

Ma ci sono anche altri modi per farlo. Ecco i più comuni.

Il modo corretto (nuovo da SQL Server 2008):

cast(getdate() As Date)

Il modo corretto (vecchio):

dateadd(dd, datediff(dd,0, getDate()), 0)

Ora è più vecchio, ma vale comunque la pena saperlo perché può anche adattarsi facilmente ad altri punti temporali, come il primo momento del mese, il minuto, l'ora o l'anno.

Questo modo corretto utilizza funzioni documentate che fanno parte dello standard ansi e sono garantite per funzionare, ma può essere un po' più lento. Funziona trovando quanti giorni ci sono dal giorno 0 al giorno corrente e aggiungendo quel numero di giorni al giorno 0. Funzionerà indipendentemente da come è memorizzato il tuo datetime e indipendentemente dalla tua lingua.

Il modo più veloce:

cast(floor(cast(getdate() as float)) as datetime)

Funziona perché le colonne datetime sono archiviate come valori binari a 8 byte. Lanciali in modo che fluttuano, mettili a terra per rimuovere la frazione e la parte temporale dei valori scompare quando li riporti a datetime. È tutto solo un po' mutevole senza una logica complicata ed è molto veloce.

Tieni presente che questo si basa su un dettaglio di implementazione che Microsoft è libera di modificare in qualsiasi momento, anche in un aggiornamento automatico del servizio. Inoltre non è molto portatile. In pratica, è molto improbabile che questa implementazione cambi a breve, ma è comunque importante essere consapevoli del pericolo se si sceglie di utilizzarla. E ora che abbiamo la possibilità di eseguire il cast come appuntamento, raramente è necessario.

Il modo sbagliato:

cast(convert(char(11), getdate(), 113) as datetime)

Il modo sbagliato funziona convertendo in una stringa, troncando la stringa e riconvertendo in un datetime. È sbagliato , per due motivi:1) potrebbe non funzionare in tutte le versioni locali e 2) si tratta del modo più lento possibile per farlo... e non solo di poco; è come un ordine di grandezza o due più lento rispetto alle altre opzioni.

Aggiorna Questo ha ottenuto alcuni voti ultimamente, e quindi voglio aggiungere che da quando ho pubblicato questo ho visto alcune prove piuttosto solide che Sql Server ottimizzerà la differenza di prestazioni tra il modo "corretto" e il modo "veloce", il che significa che ora dovresti favorire il primo.

In entrambi i casi, vuoi scrivere le tue domande per evitare la necessità di farlo in primo luogo . È molto raro che tu debba fare questo lavoro sul database.

Nella maggior parte dei casi, il database è già il tuo collo di bottiglia. In genere è il server più costoso a cui aggiungere hardware per migliorare le prestazioni e il più difficile per ottenere queste aggiunte correttamente (è necessario bilanciare i dischi con la memoria, ad esempio). È anche il più difficile da scalare verso l'esterno, sia dal punto di vista tecnico che dal punto di vista aziendale; tecnicamente è molto più semplice aggiungere un server Web o applicativo rispetto a un server di database e anche se fosse falso non si pagano più di $ 20.000 per licenza server per IIS o apache.

Il punto che sto cercando di sottolineare è che, quando possibile, dovresti fare questo lavoro a livello di applicazione. Il solo l'ora in cui dovresti trovarti a troncare un datetime su Sql Server è quando devi raggruppare per giorno, e anche allora dovresti probabilmente avere una colonna aggiuntiva impostata come colonna calcolata, mantenuta al momento dell'inserimento/aggiornamento o mantenuta nell'applicazione logica. Elimina dal database questo lavoro che rompe gli indici e pesante per la CPU.