Si encuentras algo que no comprendes puedes comentarlo y te ayudaremos lo mas rápido que podamos.
Solución:
Revisé tu perfil y vi que estás en el Reino Unido. Si su servidor sql está configurado para usar el formato de fecha dmy, eso explica su problema. Sin usar la ‘T’ en lugar del espacio en la fecha y hora stringSql Server no lo reconocerá como formato ISO8601.
Prueba esto:
select count(*)
from dbo.profile
where [created] between convert(datetime,'2014-11-01T00:00:00.000')
and convert(datetime,'2014-11-30T23:59:59.997');
Consultar usando fechas y/o fechas y horas puede ser complicado, para asegurarse de que está obteniendo lo que está buscando, le recomiendo leer:
- Los malos hábitos de Aaron Bertrand para patear: mal manejo de consultas de fecha/rango
- Banco de trabajo de FECHA/HORA del servidor SQL de Robyn Page
editar: para aclarar el valor fuera de rango en su mensaje de error sería interpretar el mes como 30 y el día como 11.
No entiendo por qué los datos se convierten de varchar a fecha y hora cuando ‘Creado’ está configurado en fecha y hora
Los literales que está proporcionando para la comparación con el Created
columna son cadenas. Para comparar esos literales con los datetime
columna, SQL Server intenta convertir las cadenas a datetime
tipos, de acuerdo con las reglas de precedencia de tipos de datos. Sin información explícita sobre el formato de las cadenas, SQL Server sigue sus intrincadas reglas para interpretar cadenas como fechas y horas.
Desde mi punto de vista, la forma más ordenada de evitar este tipo de problemas es ser explícito acerca de los tipos. SQL Server proporciona la CAST and CONVERT
funciones para este fin. Al trabajar con cadenas y tipos de fecha/hora, CONVERT
es preferible porque proporciona un parámetro de estilo para definir explícitamente el string formato.
La pregunta utiliza cadenas en formato canónico ODBC (con milisegundos) (estilo 121). Ser explícito sobre el tipo de datos y string estilo da como resultado lo siguiente:
SELECT COUNT(*)
FROM dbo.profile
WHERE [Created] BETWEEN
CONVERT(datetime, '2014-11-01 00:00:00.000', 121)
AND
CONVERT(datetime, '2014-11-30 23:59:59.997', 121);
Dicho esto, hay buenas razones (como señala Aaron en su respuesta) para usar un rango semiabierto en lugar de BETWEEN
(Utilizo el estilo 120 a continuación solo por variedad):
SELECT COUNT(*)
FROM dbo.profile
WHERE
[Created] >= CONVERT(datetime, '2014-11-01 00:00:00', 120)
AND [Created] < CONVERT(datetime, '2014-12-01 00:00:00', 120);
Ser explícito con los tipos es un muy buen hábito, especialmente cuando se trata de fechas y horas.
Ya que BETWEEN
es muy problemático debido al redondeo de diferentes tipos de fecha/hora y otros problemas, y dado que YYYY-MM-DD
no es un formato seguro sin la incomodidad T
una gama abierta que utiliza la norma ISO fechas completas sin separadores es un enfoque mucho mejor:
WHERE Created >= '20141101' AND Created < '20141201';
valoraciones y comentarios
Si tienes algún reparo o forma de aumentar nuestro post eres capaz de ejecutar una reseña y con gusto lo leeremos.