Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como posso truncar um datetime no SQL Server?


Isso continua a reunir votos adicionais com frequência, mesmo vários anos depois, e por isso preciso atualizá-lo para versões modernas do Sql Server. Para Sql Server 2008 e posterior, é simples:
cast(getDate() As Date)

Observe que os últimos três parágrafos próximos ao final ainda se aplicam, e muitas vezes você precisa dar um passo para trás e encontrar uma maneira de evitar o elenco em primeiro lugar.

Mas há outras maneiras de fazer isso também. Aqui estão os mais comuns.

A maneira correta (nova desde o Sql Server 2008):
cast(getdate() As Date)

A maneira correta (antiga):
dateadd(dd, datediff(dd,0, getDate()), 0)

Isso é mais antigo agora, mas ainda vale a pena saber porque também pode se adaptar facilmente a outros pontos de tempo, como o primeiro momento do mês, minuto, hora ou ano.

Essa maneira correta usa funções documentadas que fazem parte do padrão ansi e têm garantia de funcionamento, mas pode ser um pouco mais lenta. Ele funciona descobrindo quantos dias existem desde o dia 0 até o dia atual e adicionando esses muitos dias de volta ao dia 0. Ele funcionará independentemente de como seu datetime está armazenado e não importa qual seja sua localidade.

O caminho mais rápido:
cast(floor(cast(getdate() as float)) as datetime)

Isso funciona porque as colunas de data e hora são armazenadas como valores binários de 8 bytes. Lance-os para flutuar, coloque-os no chão para remover a fração e a parte de tempo dos valores desaparecerá quando você os lançar de volta para datetime. Está tudo mudando um pouco sem lógica complicada e é muito velozes.

Esteja ciente de que isso depende de um detalhe de implementação que a Microsoft pode alterar a qualquer momento, mesmo em uma atualização automática de serviço. Também não é muito portátil. Na prática, é muito improvável que essa implementação mude tão cedo, mas ainda é importante estar ciente do perigo se você optar por usá-la. E agora que temos a opção de lançar como uma data, raramente é necessário.

O caminho errado:
cast(convert(char(11), getdate(), 113) as datetime)

A maneira errada funciona convertendo para uma string, truncando a string e convertendo de volta para uma data e hora. Está errado , por dois motivos:1) pode não funcionar em todas as localidades e 2) é a maneira mais lenta possível de fazer isso... e não apenas um pouco; é como uma ordem de magnitude ou duas mais lenta que as outras opções.

Atualizar Isso tem recebido alguns votos ultimamente e, portanto, quero acrescentar que, desde que postei isso, vi algumas evidências bastante sólidas de que o Sql Server otimizará a diferença de desempenho entre a maneira "correta" e a maneira "rápida", significando que agora você deve favorecer o primeiro.

Em ambos os casos, você deseja escrever suas consultas para evitar a necessidade de fazer isso em primeiro lugar . É muito raro que você faça esse trabalho no banco de dados.

Na maioria dos lugares, o banco de dados já é seu gargalo. Geralmente, é o servidor mais caro para adicionar hardware para melhorias de desempenho e o mais difícil de obter essas adições corretamente (você precisa equilibrar discos com memória, por exemplo). É também o mais difícil de expandir, tanto tecnicamente quanto do ponto de vista comercial; é muito mais fácil tecnicamente adicionar um servidor web ou de aplicativos do que um servidor de banco de dados e, mesmo que isso seja falso, você não paga mais de US$ 20.000 por licença de servidor para IIS ou apache.

O ponto que estou tentando fazer é que, sempre que possível, você deve fazer esse trabalho no nível do aplicativo. O somente a hora em que você deve se encontrar truncando um datetime no Sql Server é quando você precisa agrupar por dia, e mesmo assim você provavelmente deve ter uma coluna extra configurada como uma coluna computada, mantida na hora da inserção/atualização ou mantida no aplicativo lógica. Tire esse trabalho pesado de CPU e quebra de índice do seu banco de dados.