¿SQL Server datetime como seleccionar?


92

en MySQL

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

¿Cuál es la sintaxis en SQL Server?


¿Qué es lo que realmente quiere comprobar? ¿Que una fecha y hora determinada tiene una parte de fecha determinada? ¿O algo mas?
Chris J

1
Para una discusión sana sobre esto (incluyendo por qué es malo tratar los DATETIMEvalores como cadenas, y por qué puede ser malo usar BETWEENo >= AND <=), vea este blog de Aaron Bertrand .
Aaron Bertrand

Su pregunta tiene al menos 5votos para la etiqueta de operador similar . ¿Puedo solicitarle amablemente que sugiera sql-like como sinónimo ?
Kermit

Respuestas:


138

Puede utilizar la función DATEPART ()

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

Encuentro esta forma fácil de leer, ya que ignora el componente de tiempo, y no tiene que usar la fecha del día siguiente para restringir su selección. Puede ir a mayor o menor granularidad agregando cláusulas adicionales, utilizando el código DatePart apropiado, por ejemplo

AND    DATEPART(hh, register_date) = 12)

para obtener registros realizados entre 12 y 1.

Consulte los documentos de MSDN DATEPART para obtener la lista completa de argumentos válidos.


Si hay un índice en register_date, esto ignorará por completo el índice y el rendimiento se verá afectado. Probablemente bastante mal.
Chris J

Ok, pero evita el problema de usar la cadena equivalente al día después de la fecha en cuestión, que se sugiere en algunas de las respuestas aquí. Difícil cuando la fecha en cuestión es el final del mes o el año.
Ralph Lavelle

60

No hay soporte directo para el operador LIKE contra las variables DATETIME, pero siempre puede convertir el DATETIME en un VARCHAR:

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

Consulte los documentos de MSDN para obtener una lista completa de los "estilos" disponibles en la función CONVERTIR.

Bagazo


1
estuvo de acuerdo, pero el OP solicitó una forma de manejar la fecha y hora con LIKE ... Pero estoy de acuerdo: las fechas deben manejarse preferiblemente con rangos como> = y <= o ENTRE - enfoque mucho mejor
marc_s

Gracias a todos. Lo siento, solo soy un novato en SQL.
Paisal

1
Tenga en cuenta que MSSQL 2012 (supongo que las versiones anteriores también) convertirá datetime a varchar como '2014-01-06T16: 18: 00.045', así que tenga esto en cuenta si también intenta hacer coincidir la hora / minuto.
balint

El único problema que tuve con la selección de sql anterior es este: WHERE CONVERT(VARCHAR(25), register_date, 25) LIKE '2009-10-10%'
Gabriel Marius Popescu

10

Si lo hace, lo está forzando a realizar una conversión de cadena. Sería mejor crear un rango de fechas de inicio / finalización y 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

Esto le permitirá usar el índice (si hay uno register_date), en lugar de un escaneo de tabla.


Gracias. Lo siento, solo soy un novato en SQL.
Paisal

8

Puede usar CONVERT para obtener la fecha en forma de texto. Si lo convierte a varchar (10), puede usar = en lugar de like:

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

O puede usar una fecha límite superior e inferior, con la ventaja adicional de que podría hacer uso de un índice:

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

Creo que hay un error tipográfico en la cláusula where, debería ser "where '2009-10-10'> = register_date"
Vishwanath Dalvi

@mr_eclair: no lo creo, eso incluiría todas las fechas antes del 11 de octubre
Andomar

7

Desafortunadamente, no es posible comparar datetime con varchar usando 'LIKE' Pero la salida deseada es posible de otra manera.

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

3

También puede usar convertir para que la fecha se pueda buscar usando LIKE. Por ejemplo,

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

2

El LIKEoperador no trabaja con partes de fecha como mes o fecha, pero sí lo DATEPARThace.

Comando para averiguar todas las cuentas cuya fecha de apertura fue el día 1:

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

* CASTING OpenDtporque su valor está en DATETIMEy no solo DATE.


1

Hay una cobertura muy irregular del operador LIKE para fechas en SQL Server. Solo funciona con formato de fecha estadounidense. Como ejemplo, podría intentar:

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

Probé esto en SQL Server 2005 y funciona, pero realmente necesitará probar diferentes combinaciones. Cosas extrañas que he notado son:

  • Parece que solo obtiene todo o nada para diferentes subcampos dentro de la fecha, por ejemplo, si busca 'apr 2%', solo obtiene algo en los años 20: omite los segundos.

  • El uso de un único guión bajo '_' para representar un solo carácter (comodín) no del todo trabajo, por ejemplo, WHERE mydate LIKE 'oct _ 2010%'va a no devolver todas las fechas antes del 10 - no devuelve nada en absoluto, de hecho!

  • El formato es rígido americano: ' mmm dd yyyy hh:mm'

Me ha resultado difícil concretar un proceso durante unos segundos, así que si alguien quiere llevar esto un poco más lejos, ¡sea mi invitado!

Espero que esto ayude.


1

Llegué un poco tarde a este hilo, pero de hecho hay soporte directo para el operador similar en el servidor MS SQL.

Como se documenta en la ayuda de LIKE, si el tipo de datos no es una cadena, se intenta convertirlo en una cadena. Y como se documenta en la documentación de cast \ convert:

La conversión de fecha y hora predeterminada a cadena es de tipo 0 (, 100) que es mon dd yyyy hh: miAM (o PM).

Si tiene una fecha como esta en la base de datos:

2015-06-01 11:52:59.057

y haces 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'

obtienes esa fila.

Sin embargo, este formato de fecha sugiere que es un DateTime2 , luego la documentación dice:

21 o 121: ODBC canónico (con milisegundos) predeterminado para la hora, la fecha, la fecha y la hora2 y el desplazamiento de fecha y hora. - aaaa-mm-dd hh: mi: ss.mmm (24 h)

Eso lo hace más fácil y puede usar:

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

y obtenga el registro de la factura. Aquí hay un código de demostración:

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%';

Hacer búsquedas de fecha y hora en el servidor SQL sin ninguna conversión a cadena siempre ha sido problemático. Obtener cada parte de la fecha es una exageración (que es poco probable que use un índice). Probablemente una mejor manera cuando no usa la conversión de cadenas sería usar verificaciones de rango. es decir:

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

1

Prueba esto

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

0

Resolví mi problema de esa manera. Gracias por las sugerencias de mejora. Ejemplo en 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 + "%'";
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.