Se você deseja obter um tipo de dados de data sem o horário, mesmo se o horário for 00:00:00, você está sem sorte, pode obter um varchar, mas a estrutura é um horário e você sempre terá algum tempo.
@Rohit Você está assumindo incorretamente que 2008 é a única versão com a qual as pessoas se preocupam. (Existem mais versões na natureza.) Os votos falam por si.
Htegner
Respostas:
2487
Em geral SQL Server 2008, você deve CONVERTnamorar:
SELECTCONVERT(date, getdate())
Nas versões mais antigas, você pode fazer o seguinte:
+1 Parece que este é 35% mais rápido que o método double convert () comumente usado (que eu também uso há anos). Agradável.
Dane
8
A única desvantagem que vejo na sua solução é que, a menos que você saiba o que está fazendo, é um pouco obtuso. O uso do método de conversão dupla torna suas intenções mais óbvias para os mantenedores de códigos futuros. Aliás, eu não te diminuiu. Acho que vou começar a usar seu método também. Obrigado @aku
Jim Birchall
38
@pilavdzice Definir uma data e hora para a meia-noite daquele dia não deixar de fora o tempo todo. Que resultado você está esperando? O datetimetipo de dados não pode ter tempo . Eu acho que você está confundindo armazenamento de dados com apresentação do usuário. Se tudo o que você deseja é uma maneira de mostrar a um usuário uma string que não tem parte do tempo (não zera, apenas espaços em branco), você simplesmente deseja Convert(varchar(30), @Date, 101)ou algo semelhante. Consulte Manuais Online do SQL Server • Conversão e conversão para obter mais informações.
precisa saber é o seguinte
7
@ user1671639 o tipo de dados datetime sempre contém uma data e uma hora; você não pode armazenar um sem sensatez, a menos que esteja usando o SQL Server 2008; nesse caso, também existem dados separados de 'date' e 'time' tipos. Se você usar CONVERT () assim, realmente deseja uma string para uso posterior, para que fique preso dessa maneira - embora seja melhor se você use funções de formatação de data em vez de cortar a data - ou via CAST(... AS DATE)ou CONVERT(DATE, ...), que já foi mencionado com frequência nesta página.
Magnus
10
Eu recomendo alterar a resposta para, SELECT DATEADD(dd, DATEDIFF(dd, 0, @your_date), 0)porque então ddpode ser trocada por qualquer outra datepartpalavra-chave para truncar a sua datetimeem um nível arbitrário.
Michael - Onde está Clay Shirky
717
O SQLServer 2008 agora tem um tipo de dados 'date' que contém apenas uma data sem componente de hora. Qualquer pessoa que use o SQLServer 2008 e além pode fazer o seguinte:
Há também o tipo de dados 'time' no SQL2008, que responde à outra metade da questão de separar data e hora.
misteraidan
8
Para sua informação, comparei diferentes métodos de aparar o tempo das datas e esse foi o método mais rápido. Concedido que a diferença era pequena, mas era claramente mais rápida em um grande número de execuções.
@ Nick, para complementar a resposta do abatishchev, o seu @ date1 é de fato 2015-10-01devido a DateTimelimitações. Tente sem elenco Date, ele 2015-10-01também rende ! declare @date1 datetime = '2015-09-30 23:59:59.999';select @date1=>2015-10-01
Frédéric
4
Um desses truques fáceis de lembrar do SQL. Como Mike diz, somente em 2008, mas, se você encontrar um banco de dados de 2005 e anterior em algum lugar, poderá ter muitos problemas :) #
31515 NicVerAZ
73
DATEADD e DATEDIFF são melhores que CONVERTING para varchar. Ambas as consultas têm o mesmo plano de execução, mas os planos de execução são principalmente sobre estratégias de acesso a dados e nem sempre revelam custos implícitos envolvidos no tempo de CPU necessário para executar todas as peças. Se as duas consultas forem executadas em uma tabela com milhões de linhas, o tempo da CPU usando DateDiff poderá ser próximo a 1/3 do tempo da CPU de conversão!
Para ver os planos de execução de consultas:
set showplan_text on
GO
DATEADD e DATEDIFF executarão um CONVERT_IMPLICIT.
Embora a solução CONVERT seja mais simples e fácil de ler para alguns, é mais lenta. Não é necessário retroceder para a data e hora (isso é implicitamente feito pelo servidor). Também não há necessidade real no método DateDiff para o DateAdd posteriormente, pois o resultado inteiro também será implicitamente convertido novamente em datetime.
SELECT CONVERT (varchar, MyDate, 101) FROM DatesTable
O uso de FLOOR () como @digi sugerido tem desempenho mais próximo de DateDiff, mas não é recomendado, pois converter o tipo de dados de data e hora para flutuar e voltar nem sempre gera o valor original.
Lembre-se de caras: não acredite em ninguém. Veja as estatísticas de desempenho e teste você mesmo!
Tenha cuidado ao testar seus resultados. A seleção de muitas linhas para o cliente ocultará a diferença de desempenho, pois leva mais tempo para enviar as linhas pela rede do que para executar os cálculos. Portanto, verifique se o trabalho para todas as linhas é feito pelo servidor, mas não há um conjunto de linhas enviado ao cliente.
Parece haver confusão para algumas pessoas sobre quando a otimização do cache afeta as consultas. A execução de duas consultas no mesmo lote ou em lotes separados não afeta o cache. Portanto, você pode expirar o cache manualmente ou simplesmente executar as consultas várias vezes. Qualquer otimização para a consulta nº 2 também afetaria as consultas subseqüentes; portanto, descarte a execução nº 1, se desejar.
Ricardo C, boa investigação! Qual versão do SQL server você usa? No método MSSQL2000 com datediff executa um pouco mais rápido para mim.
aku
Apenas para observar, eu realizei o teste 1000.000 vezes. Para cenários do mundo real diferença de desempenho não será perceptível, eu acho
aku
Aku, usei o SQL Server 2005 Express para este teste. Eu trabalho em 2000 no trabalho e vou testá-lo com uma tabela com mais de 24 milhões de linhas e ver o que sai dele.
Ricardo C
Aku, mesmos resultados. Não há diferença no desempenho em mais de dez milhões de linhas.
Ricardo C
5
As alegações sobre desempenho igual não são verdadeiras. Claro que os planos de execução serão os mesmos !!! A medição do desempenho nesses DEVE ser feita comparando o uso da CPU, não examinando os planos de execução.
ErikE
51
Tente o seguinte:
SELECTCONVERT(VARCHAR(10),GETDATE(),111)
A declaração acima converte seu formato atual para YYYY/MM/DD, consulte este link para escolher seu formato preferencial.
Esse método não é o mais rápido e também ensina implicitamente às pessoas que as datas de lançamento para flutuação são precisas, o que não é. Por favor, consulte este post para mais detalhes.
ErikE
13
Se você estiver usando o SQL Server 2012 ou versões posteriores ,
Já existem várias respostas e tipos de formatação para o SQL server. Mas a maioria dos métodos é um tanto ambígua e seria difícil lembrar os números para o tipo ou funções de formato em relação ao formato específico da data. É por isso que nas próximas versões do SQL Server há uma opção melhor.
FORMAT ( value, format [, culture ])
A opção Cultura é muito útil, pois você pode especificar a data conforme seus espectadores.
Você deve se lembrar de d (para padrões pequenos) e D (para padrões longos).
2009-06-15T13:45:30-> Monday, June 15,2009(en-US)2009-06-15T13:45:30->15июня2009г.(ru-RU)2009-06-15T13:45:30-> Montag,15. Juni 2009(de-DE)
Mais exemplos na consulta.
DECLARE@d DATETIME ='10/01/2011';SELECT FORMAT (@d,'d','en-US')AS'US English Result',FORMAT (@d,'d','en-gb')AS'Great Britain English Result',FORMAT (@d,'d','de-de')AS'German Result',FORMAT (@d,'d','zh-cn')AS'Simplified Chinese (PRC) Result';SELECT FORMAT (@d,'D','en-US')AS'US English Result',FORMAT (@d,'D','en-gb')AS'Great Britain English Result',FORMAT (@d,'D','de-de')AS'German Result',FORMAT (@d,'D','zh-cn')AS'Chinese (Simplified PRC) Result';
US English Result Great Britain English Result German Result Simplified Chinese (PRC) Result
---------------- ----------------------------- ------------- -------------------------------------10/1/201101/10/201101.10.20112011/10/1
US English Result Great Britain English Result German Result Chinese (Simplified PRC) Result
---------------------------- ----------------------------- ----------------------------- ---------------------------------------
Saturday, October 01,201101 October 2011 Samstag,1. Oktober 20112011年10月1日
Se você deseja usar CONVERT e obter a mesma saída da pergunta original, ou seja, aaaa-mm-dd, use o CONVERT(varchar(10),[SourceDate as dateTime],121)mesmo código das respostas anteriores, mas o código para converter para aaaa-mm-dd com traços é 121
Se eu puder entrar na minha caixa de sabão por um segundo, esse tipo de formatação não pertence à camada de dados , e é por isso que não era possível sem os 'truques' bobos de sobrecarga até o SQL Server 2008, quando os tipos de dados reais da parte de data são introduzido. Fazer essas conversões na camada de dados é um enorme desperdício de sobrecarga no DBMS, mas o mais importante é que, no momento em que você faz algo parecido com isso, você basicamente cria dados órfãos na memória que eu suponho que você retornará a um programa. Você não pode colocá-lo novamente em outra coluna 3NF + ou compará-lo com qualquer coisa digitada sem reverter, portanto tudo o que você fez foi introduzir pontos de falha e remover a referência relacional.
SEMPRE siga em frente e retorne seu tipo de dados dateTime ao programa de chamada e, na camada APRESENTAÇÃO, faça os ajustes necessários. Assim que você converter as coisas antes de devolvê-las ao chamador, estará removendo toda a esperança de integridade referencial do aplicativo. Isso impediria uma operação UPDATE ou DELETE, novamente, a menos que você faça algum tipo de reversão manual, que novamente expõe seus dados a erro humano / código / gremlin quando não há necessidade.
Exceto, por exemplo, se você desejar uma consulta que recupere todos os registros correspondentes a uma data fornecida pelo usuário como a parte da data de um determinado campo de tempo. Boa sorte fazendo isso apenas na camada de apresentação. (Você não precisa converter, você pode pode usar a data aritmética, mas você começa a idéia ...)
Andrew Lazarus
1
@ Andrew, por que isso importa? Você diz WHERE col >= @Date AND col < DATEADD(DAY, 1, @Date);- não há absolutamente nenhuma razão para retirar o tempo da coluna.
Aaron Bertrand
1
@AaronBertrand Isso funciona apenas assumindo que a entrada @Datetem uma parte do tempo zero. Caso isso não seja verdade, você ainda precisará saber como truncar os horários do servidor. Concordo com esta resposta que a formatação deve ser deixada para a camada de apresentação, mas não concordo com a implicação de que deixar isso para o front end significa que você não precisa conhecer uma maneira rápida de truncar.
Andrew Lazarus
1
@ Andrew, tudo o que você precisa fazer é definir o parâmetro de entrada DATE. Meu argumento ainda é que você nunca deve aplicar tal truncamento à coluna , mesmo que esse seja o primeiro instinto da maioria das pessoas.
Aaron Bertrand
1
@AaronBertrand e isso pressupõe que você tenha controle sobre o tipo de dados do parâmetro. Fino em um procedimento armazenado, não é possível em outras situações. Por que não transmitir para garantir que o parâmetro seja do tipo que você deseja e precisa?
Esses métodos são ótimos, mas qual deles você sugere usar?
eddiegroves
3
Note-se que a versão "correta" do topo dois é select dateadd(dd, datediff(dd, 0, getdate()), 0), porque os dds podem então ser trocados por qualquer uma das datepartpalavras-chave para cortar a data em qualquer segmento que você escolher. (Note também que ddé apenas uma abreviação para day.)
Michael - Onde está Clay Shirky
10
Para obter o resultado indicado, eu uso o seguinte comando.
Seu primeiro exemplo ainda tem um componente de tempo. O objetivo da pergunta era como remover isso.
Zack
5
Mesmo usando o antigo MSSQL Server 7.0, o código aqui (cortesia deste link ) me permitiu obter qualquer formato de data que eu estava procurando na época:
PRINT'1) Date/time in format MON DD YYYY HH:MI AM (OR PM): '+CONVERT(CHAR(19),GETDATE())PRINT'2) Date/time in format MM-DD-YY: '+CONVERT(CHAR(8),GETDATE(),10)PRINT'3) Date/time in format MM-DD-YYYY: '+CONVERT(CHAR(10),GETDATE(),110)PRINT'4) Date/time in format DD MON YYYY: '+CONVERT(CHAR(11),GETDATE(),106)PRINT'5) Date/time in format DD MON YY: '+CONVERT(CHAR(9),GETDATE(),6)PRINT'6) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H): '+CONVERT(CHAR(24),GETDATE(),113)
Produziu esta saída:
1) Date/time in format MON DD YYYY HH:MI AM (OR PM): Feb 2720151:14PM
2) Date/time in format MM-DD-YY:02-27-153) Date/time in format MM-DD-YYYY:02-27-20154) Date/time in format DD MON YYYY:27 Feb 20155) Date/time in format DD MON YY:27 Feb 156) Date/time in format DD MON YYYY HH:MM:SS:MMM(24H):27 Feb 201513:14:46:630
select {fn current_date()} as todayfunciona para mim.
Brianary
@ brianary - Isso é legal, mas não é ANSI SQL.
iluminado
Isso é justo o suficiente, e sua resposta é bem portátil, mas imaginei que, enquanto trabalhamos com o T-SQL, isso também funciona (e mostra que a implementação do ANSI CURRENT_DATE seria trivial para o MS).
Também não se importa com o local ou faz uma conversão dupla - embora cada 'datepart' provavelmente faça matemática. Portanto, pode ser um pouco mais lento que o método datado, mas para mim é muito mais claro. Especialmente quando eu quero agrupar apenas o ano e o mês (defina o dia como 1).
Você pode usar o seguinte para a parte da data e formatar a data:
DATENAME => Retorna uma cadeia de caracteres que representa o período especificado da data especificada
DATEADD => A DATEPART()função é usada para retornar uma única parte de uma data / hora, como ano, mês, dia, hora, minuto, etc.
DATEPART => Retorna um número inteiro que representa o período especificado da data especificada.
CONVERT()=> A CONVERT()função é uma função geral que converte uma expressão de um tipo de dados para outro. A
CONVERT()função pode ser usada para exibir dados de data / hora em diferentes formatos.
Respostas:
Em geral
SQL Server 2008
, você deveCONVERT
namorar:Nas versões mais antigas, você pode fazer o seguinte:
por exemplo
me dá
Prós:
varchar
<->datetime
locale
Como sugerido por Michael
Use esta variante:
SELECT DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)
Resultado:
fonte
datetime
tipo de dados não pode ter tempo . Eu acho que você está confundindo armazenamento de dados com apresentação do usuário. Se tudo o que você deseja é uma maneira de mostrar a um usuário uma string que não tem parte do tempo (não zera, apenas espaços em branco), você simplesmente desejaConvert(varchar(30), @Date, 101)
ou algo semelhante. Consulte Manuais Online do SQL Server • Conversão e conversão para obter mais informações.CAST(... AS DATE)
ouCONVERT(DATE, ...)
, que já foi mencionado com frequência nesta página.SELECT DATEADD(dd, DATEDIFF(dd, 0, @your_date), 0)
porque entãodd
pode ser trocada por qualquer outradatepart
palavra-chave para truncar a suadatetime
em um nível arbitrário.O SQLServer 2008 agora tem um tipo de dados 'date' que contém apenas uma data sem componente de hora. Qualquer pessoa que use o SQLServer 2008 e além pode fazer o seguinte:
fonte
Se estiver usando o SQL 2008 e acima:
fonte
DateTime2
vez disso e funciona bem. sqlfiddle.com/#!6/9eecb7/28332015-10-01
devido aDateTime
limitações. Tente sem elencoDate
, ele2015-10-01
também rende !declare @date1 datetime = '2015-09-30 23:59:59.999';select @date1
=>2015-10-01
DATEADD e DATEDIFF são melhores que CONVERTING para varchar. Ambas as consultas têm o mesmo plano de execução, mas os planos de execução são principalmente sobre estratégias de acesso a dados e nem sempre revelam custos implícitos envolvidos no tempo de CPU necessário para executar todas as peças. Se as duas consultas forem executadas em uma tabela com milhões de linhas, o tempo da CPU usando DateDiff poderá ser próximo a 1/3 do tempo da CPU de conversão!
Para ver os planos de execução de consultas:
DATEADD e DATEDIFF executarão um CONVERT_IMPLICIT.
Embora a solução CONVERT seja mais simples e fácil de ler para alguns, é mais lenta. Não é necessário retroceder para a data e hora (isso é implicitamente feito pelo servidor). Também não há necessidade real no método DateDiff para o DateAdd posteriormente, pois o resultado inteiro também será implicitamente convertido novamente em datetime.
SELECT CONVERT (varchar, MyDate, 101) FROM DatesTable
SELECT DATEADD (dd, 0, DATEDIFF (dd, 0, MyDate)) FROM DatesTable
O uso de FLOOR () como @digi sugerido tem desempenho mais próximo de DateDiff, mas não é recomendado, pois converter o tipo de dados de data e hora para flutuar e voltar nem sempre gera o valor original.
Lembre-se de caras: não acredite em ninguém. Veja as estatísticas de desempenho e teste você mesmo!
Tenha cuidado ao testar seus resultados. A seleção de muitas linhas para o cliente ocultará a diferença de desempenho, pois leva mais tempo para enviar as linhas pela rede do que para executar os cálculos. Portanto, verifique se o trabalho para todas as linhas é feito pelo servidor, mas não há um conjunto de linhas enviado ao cliente.
Parece haver confusão para algumas pessoas sobre quando a otimização do cache afeta as consultas. A execução de duas consultas no mesmo lote ou em lotes separados não afeta o cache. Portanto, você pode expirar o cache manualmente ou simplesmente executar as consultas várias vezes. Qualquer otimização para a consulta nº 2 também afetaria as consultas subseqüentes; portanto, descarte a execução nº 1, se desejar.
Aqui estão os resultados completos do script de teste e desempenho que provam que o DateDiff é substancialmente mais rápido do que converter para varchar.
fonte
Tente o seguinte:
A declaração acima converte seu formato atual para
YYYY/MM/DD
, consulte este link para escolher seu formato preferencial.fonte
mm/dd/yyyy
formato.fonte
Para retorno em formato de data
O código acima funcionará no sql server 2010
Voltará como 12/12/2013
Para o SQL Server 2012, use o código abaixo
fonte
Você pode usar a
CONVERT
função para retornar apenas a data. Veja os links abaixo:Manipulação de data e hora no SQL Server 2000
CAST e CONVERT
A sintaxe para usar a função convert é:
fonte
Se você precisar do resultado como um
varchar
, deve passar porque já foi mencionado acima.
Se você precisar resultar no formato de data e hora, use qualquer uma das consultas abaixo
fonte
fonte
Usando FLOOR () - basta cortar parte do tempo.
fonte
Se você estiver usando o SQL Server 2012 ou versões posteriores ,
Use a
Format()
funçãoJá existem várias respostas e tipos de formatação para o SQL server. Mas a maioria dos métodos é um tanto ambígua e seria difícil lembrar os números para o tipo ou funções de formato em relação ao formato específico da data. É por isso que nas próximas versões do SQL Server há uma opção melhor.
A opção Cultura é muito útil, pois você pode especificar a data conforme seus espectadores.
Você deve se lembrar de d (para padrões pequenos) e D (para padrões longos).
1. "d" - padrão de data curta.
2. "D" - padrão de data longa.
Mais exemplos na consulta.
Se você quiser mais formatos, pode ir para:
fonte
Se você deseja usar CONVERT e obter a mesma saída da pergunta original, ou seja, aaaa-mm-dd, use o
CONVERT(varchar(10),[SourceDate as dateTime],121)
mesmo código das respostas anteriores, mas o código para converter para aaaa-mm-dd com traços é 121Se eu puder entrar na minha caixa de sabão por um segundo, esse tipo de formatação não pertence à camada de dados , e é por isso que não era possível sem os 'truques' bobos de sobrecarga até o SQL Server 2008, quando os tipos de dados reais da parte de data são introduzido. Fazer essas conversões na camada de dados é um enorme desperdício de sobrecarga no DBMS, mas o mais importante é que, no momento em que você faz algo parecido com isso, você basicamente cria dados órfãos na memória que eu suponho que você retornará a um programa. Você não pode colocá-lo novamente em outra coluna 3NF + ou compará-lo com qualquer coisa digitada sem reverter, portanto tudo o que você fez foi introduzir pontos de falha e remover a referência relacional.
SEMPRE siga em frente e retorne seu tipo de dados dateTime ao programa de chamada e, na camada APRESENTAÇÃO, faça os ajustes necessários. Assim que você converter as coisas antes de devolvê-las ao chamador, estará removendo toda a esperança de integridade referencial do aplicativo. Isso impediria uma operação UPDATE ou DELETE, novamente, a menos que você faça algum tipo de reversão manual, que novamente expõe seus dados a erro humano / código / gremlin quando não há necessidade.
fonte
WHERE col >= @Date AND col < DATEADD(DAY, 1, @Date);
- não há absolutamente nenhuma razão para retirar o tempo da coluna.@Date
tem uma parte do tempo zero. Caso isso não seja verdade, você ainda precisará saber como truncar os horários do servidor. Concordo com esta resposta que a formatação deve ser deixada para a camada de apresentação, mas não concordo com a implicação de que deixar isso para o front end significa que você não precisa conhecer uma maneira rápida de truncar.Edit: Os dois primeiros métodos são essencialmente os mesmos, e executamos o método convert to varchar.
fonte
select dateadd(dd, datediff(dd, 0, getdate()), 0)
, porque osdd
s podem então ser trocados por qualquer uma dasdatepart
palavras-chave para cortar a data em qualquer segmento que você escolher. (Note também quedd
é apenas uma abreviação paraday
.)Para obter o resultado indicado, eu uso o seguinte comando.
Eu acho que é útil.
fonte
fonte
Se você estiver atribuindo os resultados a uma coluna ou variável, forneça o tipo DATE e a conversão estará implícita.
fonte
Eu acho que isso funcionaria no seu caso:
fonte
fonte
Ok, embora eu esteja um pouco atrasado :), Aqui está a outra solução.
Resultado
E se você estiver usando o SQL Server 2012 e superior, poderá usar uma
FORMAT()
função como esta -fonte
Mesmo usando o antigo MSSQL Server 7.0, o código aqui (cortesia deste link ) me permitiu obter qualquer formato de data que eu estava procurando na época:
Produziu esta saída:
fonte
Encontro:
Tempo:
fonte
Simplesmente você pode fazer desta maneira:
Saídas como:
Ou simplesmente faça assim:
Resultado:
fonte
por que você não usa DATE_FORMAT (your_datetiem_column, '% d-% m-% Y')?
EX:
select DATE_FORMAT( some_datetime_column, '%d-%m-%Y' ) from table_name
você pode alterar a sequência de m, de ano reorganizando a
'%d-%m-%Y'
partefonte
Eu sei que isso é antigo, mas não vejo onde alguém o declarou dessa maneira. Pelo que sei, esse é o padrão ANSI.
Seria bom se a Microsoft também pudesse suportar a variável CURRENT_DATE do padrão ANSI.
fonte
select {fn current_date()} as today
funciona para mim.Sou a favor do seguinte, que não foi mencionado:
Também não se importa com o local ou faz uma conversão dupla - embora cada 'datepart' provavelmente faça matemática. Portanto, pode ser um pouco mais lento que o método datado, mas para mim é muito mais claro. Especialmente quando eu quero agrupar apenas o ano e o mês (defina o dia como 1).
fonte
A partir do SQL SERVER 2012, você pode fazer isso:
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd 00:00:00.000')
fonte
No SQL Server 2000
fonte
Nesse caso, somente data, você executaremos esta consulta:
SELECT CONVERT (VARCHAR (10), getdate (), 111);
fonte
Você pode usar o seguinte para a parte da data e formatar a data:
DATENAME => Retorna uma cadeia de caracteres que representa o período especificado da data especificada
DATEADD => A
DATEPART()
função é usada para retornar uma única parte de uma data / hora, como ano, mês, dia, hora, minuto, etc.DATEPART => Retorna um número inteiro que representa o período especificado da data especificada.
CONVERT()
=> ACONVERT()
função é uma função geral que converte uma expressão de um tipo de dados para outro. ACONVERT()
função pode ser usada para exibir dados de data / hora em diferentes formatos.fonte