Data e hora do SQL Server LIKE selecionar?


92

em MySQL

select * from record where register_date like '2009-10-10%'

Qual é a sintaxe do SQL Server?


O que você realmente quer verificar? Que uma determinada data e hora tem uma determinada parte da data? Ou alguma outra coisa?
Chris J

1
Para uma discussão saudável sobre isso (incluindo por que é ruim tratar DATETIMEvalores como strings e por que pode ser ruim usar BETWEENou >= AND <=), consulte este blog de Aaron Bertrand .
Aaron Bertrand

Sua pergunta tem pelo menos 5votos para a tag de operador semelhante . Posso pedir que você sugira sql-like como sinônimo ?
Kermit

Respostas:


138

Você pode usar a função DATEPART ()

SELECT * FROM record 
WHERE  (DATEPART(yy, register_date) = 2009
AND    DATEPART(mm, register_date) = 10
AND    DATEPART(dd, register_date) = 10)

Acho essa maneira fácil de ler, pois ignora o componente de tempo e você não precisa usar a data do dia seguinte para restringir sua seleção. Você pode ir para uma granularidade maior ou menor adicionando cláusulas extras, usando o código DatePart apropriado, por exemplo

AND    DATEPART(hh, register_date) = 12)

para obter registros feitos entre 12 e 1.

Consulte os documentos MSDN DATEPART para obter a lista completa de argumentos válidos.


Se houver um índice em register_date, isso irá ignorar completamente o índice e o desempenho será prejudicado. Provavelmente muito mal.
Chris J

Ok, mas evita o problema de usar a string equivalente ao dia após a data em questão, o que está sendo sugerido em algumas das respostas aqui. Complicado quando a data em questão é o final do mês ou ano.
Ralph Lavelle

59

Não há suporte direto para o operador LIKE em relação às variáveis ​​DATETIME, mas você sempre pode converter DATETIME para um VARCHAR:

SELECT (list of fields) FROM YourTable
WHERE CONVERT(VARCHAR(25), register_date, 126) LIKE '2009-10-10%'

Verifique os documentos do MSDN para obter uma lista completa dos "estilos" disponíveis na função CONVERTER.

Marc


1
concordou - mas o OP solicitou uma maneira de lidar com datetime com LIKE .... Mas eu concordo - datetimes devem ser preferencialmente tratados com intervalos como> = e <= ou BETWEEN - abordagem muito melhor
marc_s

Obrigado a todos. Desculpe, sou apenas um novato em SQL.
Paisal

1
Esteja ciente de que o MSSQL 2012 (acho que as versões mais antigas também) converterá datetime em varchar como '2014-01-06T16: 18: 00.045', portanto, lembre-se disso se tentar fazer a correspondência para hora / minuto também.
balint

O único problema que tive com o sql select acima é este: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

10

Se você fizer isso, você o está forçando a fazer uma conversão de string. Seria melhor criar um intervalo de datas de início / término e usar:

declare @start datetime, @end datetime
select @start = '2009-10-10', @end = '2009-11-10'
select * from record where register_date >= @start
           and register_date < @end

Isso permitirá que ele use o índice (se houver register_date), em vez de uma varredura de tabela.


Obrigado. Desculpe, sou apenas um novato em SQL.
Paisal

7

Você pode usar CONVERT para obter a data em formato de texto. Se você convertê-lo em um varchar (10), pode usar = em vez de:

select *
from record
where CONVERT(VARCHAR(10),register_date,120) = '2009-10-10'

Ou você pode usar uma data limite superior e inferior, com a vantagem adicional de poder usar um índice:

select *
from record
where '2009-10-10' <= register_date
and register_date < '2009-10-11'

Acho que há erro de digitação na cláusula where, deveria ser "where '2009-10-10'> = register_date"
Vishwanath Dalvi

@mr_eclair: acho que não, isso incluiria todas as datas antes de 11 de outubro
Andomar

7

Infelizmente, não é possível comparar datetime em relação ao varchar usando 'LIKE', mas a saída desejada é possível de outra maneira.

    select * from record where datediff(dd,[record].[register_date],'2009-10-10')=0

3

Você também pode usar convert para tornar a data pesquisável usando LIKE. Por exemplo,

select convert(VARCHAR(40),create_date,121) , * from sys.objects where     convert(VARCHAR(40),create_date,121) LIKE '%17:34%'

2

O LIKEoperador não trabalha com partes de data como mês ou data, mas o DATEPARToperador sim.

Comando para descobrir todas as contas cuja data de abertura foi no dia 1º:

SELECT * 
  FROM Account 
 WHERE DATEPART(DAY, CAST(OpenDt AS DATE)) = 1`

* CASTING OpenDtporque seu valor está dentro DATETIMEe não justo DATE.


1

Há uma cobertura muito irregular do operador LIKE para datas no SQL Server. Só funciona no formato de data americano. Como exemplo, você pode tentar:

... WHERE register_date LIKE 'oct 10 2009%'

Eu testei isso no SQL Server 2005 e funciona, mas você realmente precisará tentar combinações diferentes. Coisas estranhas que notei são:

  • Você parece obter tudo ou nada para diferentes subcampos dentro da data, por exemplo, se você pesquisar 'abril 2%', você obterá apenas algo no dia 20 - ele omite o segundo.

  • Usando um único sublinhado '_' para representar um único caractere (wildcard) não inteiramente trabalho, por exemplo, WHERE mydate LIKE 'oct _ 2010%'vai não voltar todas as datas antes de o 10º - ele retorna nada, na verdade!

  • O formato é americano rígido: ' mmm dd yyyy hh:mm'

Achei difícil definir um processo por LIKEing segundos, então, se alguém quiser ir um pouco mais longe, fique à vontade!

Espero que isto ajude.


1

Estou um pouco atrasado para este tópico, mas na verdade há suporte direto para o operador semelhante no servidor MS SQL.

Conforme documentado na ajuda do LIKE, se o tipo de dados não for uma string, será tentado convertê-lo em uma string. E conforme documentado na documentação cast \ convert:

a conversão de data e hora padrão para string é do tipo 0 (, 100), que é mon dd aaaa hh: miAM (ou PM).

Se você tiver uma data como esta no DB:

2015-06-01 11:52:59.057

e você faz consultas como esta:

select * from wws_invoice where invdate like 'Jun%'
select * from wws_invoice where invdate like 'Jun 1%'
select * from wws_invoice where invdate like 'Jun 1 %'
select * from wws_invoice where invdate like 'Jun 1 2015:%'
select * from wws_invoice where invdate like 'Jun ? 2015%'
...
select * from wws_invoice where invdate like 'Jun 1 2015 11:52AM'

você obtém essa linha.

No entanto, este formato de data sugere que é um DateTime2 , então a documentação diz:

21 ou 121 - ODBC canônico (com milissegundos) padrão para hora, data, datetime2 e datetimeoffset. - aaaa-mm-dd hh: mi: ss.mmm (24h)

Isso torna tudo mais fácil e você pode usar:

select * from wws_invoice where invdate like '2015-06-01%'

e obter o registro da fatura. Aqui está um código de demonstração:

DECLARE @myDates TABLE (myDate DATETIME2);
INSERT INTO @myDates (myDate)
VALUES
('2015-06-01 11:52:59.057'),
('2015-06-01 11:52:59.054'),
('2015-06-01 13:52:59.057'),
('2015-06-01 14:52:59.057');

SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59%';
SELECT * FROM @myDates WHERE myDate LIKE '2015-06-01 11:52:59.054%';

Fazer pesquisas de data e hora no servidor SQL sem qualquer conversão em string sempre foi problemático. Obter cada parte da data é um exagero (o que provavelmente não usaria um índice). Provavelmente, a melhor maneira quando você não usa a conversão de string seria usar verificações de intervalo. ie:

select * from record 
where register_date >= '20091010' and register_date < '20091011';

1

Tente isto

SELECT top 10 * from record WHERE  IsActive = 1 and CONVERT(VARCHAR, register_date, 120) LIKE '2020-01%'

0

Resolvi meu problema dessa forma. Obrigado por sugestões de melhorias. Exemplo em C #.

string dd, mm, aa, trc, data;
dd = nData.Text.Substring(0, 2);
mm = nData.Text.Substring(3, 2);
aa = nData.Text.Substring(6, 4);
trc = "-";
data = aa + trc + mm + trc + dd;

"Select * From bdPedidos Where Data Like '%" + data + "%'";
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.