SQL «entre» no incluido

Tengo una consulta como esta:

SELECT * FROM Cases WHERE created_at BETWEEN '2013-05-01' AND '2013-05-01'

Pero esto no da resultados, aunque no hay datos en el 1er.

created_at parece 2013-05-01 22:25:19, sospecho que tiene que ver con el tiempo? ¿Cómo podía ser resuelto?

Funciona muy bien si tengo que hacer grandes rangos de fecha, pero debe (inclusive) trabajar con una sola fecha demasiado.

  • Bien, ¿cuántos son los números entre 1 y 1? Debe ser de 1,5 entre 1 y 1? no usa ENTRE la fecha/intervalos de tiempo. Nunca. Y tener cuidado de cómo evaluar «funciona bien» – ha inspeccionado de cerca los resultados de la última jornada en la gama? Sólo se incluyen todas las filas, en caso de no tener cualquier momento asociado con ellos.
  • URL actualizada para Aarón: sqlblog.org/2011/10/19/…
InformationsquelleAutor JBurace | 2013-05-02

8 Kommentare

  1. 263

    Se es inclusive. Usted está comparando datetimes de las fechas. La segunda fecha se interpreta como la medianoche cuando el día comienza.

    Una forma de solucionar esto es:

    SELECT *
    FROM Cases
    WHERE cast(created_at as date) BETWEEN '2013-05-01' AND '2013-05-01'

    Otra manera de solucionarlo es con el consentimiento explícito comparaciones binarias

    SELECT *
    FROM Cases
    WHERE created_at >= '2013-05-01' AND created_at < '2013-05-02'

    Aarón Bertrand tiene una larga entrada en el blog sobre las fechas (aquí), donde se discute este y otros problemas de la fecha.

    • La integridad del bien sobre esta buena respuesta, me gustaría sugerir el uso de dateadd para llegar al día siguiente.
    • Por el bien de una buena respuesta, yo habría usado ISO-8601 formato de ‘20130501’. Para que no NOS de las personas con dateformat dmy, se obtiene esto: set dateformat dmy;select month(cast('2013-05-01' as datetime)); =1
    • Creo que el explícita bit es el uso de un intervalo cerrado en un extremo (>=) y abierto en el otro ( < ), combinada con la comprobación de un día posterior a la fecha de finalización especificada.
    • Este tipo de problema es la razón por la que yo elija para representar fecha/horas internamente como Día Juliano Modificado los números. Siempre están con respecto a la hora UTC, en una precisión de milisegundos con sólo un doble, y puede ser fácilmente convertido en visible las formas. Por otra parte, la fecha de la aritmética, la clasificación, la comparación, y la fecha a base de filtros son triviales a implementar.
    • Personalmente, me gustaría encontrar molesto tener que convertir a datetimes cada vez que quería mostrar, la exportación, la importación, o escribir una clase con un datetime. Creo que SQL Server tiene un montón de funcionalidades integradas para manipular y comparar datetimes para la mayoría de propósitos.
    • por supuesto, la elección de cómo representar la fecha/hora depende de muchas cosas. Si la fecha de comparaciones, la aritmética o la ordenación no es un énfasis para un determinado conjunto de datos o una aplicación, o si usted está caminando en un entorno heredado que ya está estandarizado en una representación particular entonces tiene sentido ir con el flujo. Para el nuevo desarrollo de la aplicación, las ventajas de la representación de la fecha/horas internamente como universal, UTC POSIX anhela o de Día Juliano Números puede ser convincente y bien vale la pena considerar. Esta pregunta habla sólo un problema con datetimes.
    • Nunca se debe emitir una columna en la where cláusula, ya que se perderá la indexación que tiene. Es una muy mala patrón.
    • Primero es la solución perfecta para la dinámica de la fecha de las entradas.Muchas gracias.
    • ¿y si la fecha es el último día del mes? ¿cómo puedo tener una solución genérica para cada fecha del año?
    • Comentar específicamente no se aplica a la fundición para una fecha en SQL Server.
    • Si usted tiene una pregunta, pida que como una pregunta, no en un comentario.

  2. 40

    Se ha asumido que la segunda fecha de referencia en el BETWEEN sintaxis es por arte de magia se considera el «final del día», pero esto es falso.

    es decir, esto era de esperar:

    SELECT * FROM Casos 
    DONDE created_at ENTRE el principio de '2013-05-01' Y el final de '2013-05-01'

    pero lo que realmente sucede es esto:

    SELECT * FROM Casos 
    DONDE created_at ENTRE '2013-05-01 00:00:00+00000' Y '2013-05-01 00:00:00+00000' 
    

    Que se convierte en el equivalente de:

    SELECT * FROM Casos DONDE created_at = '2013-05-01 00:00:00+00000' 
    

    El problema es de percepción y expectativas sobre BETWEEN que hace incluir TANTO el valor inferior y el superior de los valores en el rango, pero no por arte de magia hacer una fecha en que el «principio de la» o «del fin».

    BETWEEN deben evitarse a la hora de filtrar por rangos de fecha.

    Siempre utilizar el >= AND < lugar

    SELECT * FROM Casos 
    DONDE (created_at >= '20130501' Y created_at < '20130502')

    los paréntesis son opcionales aquí, pero pueden ser importantes en consultas más complejas.

    • Dudas sobre la sabiduría de la publicación de este bien después de que la pregunta ya ha sido contestada, pero quería destacar algo un poco diferente punto de
    • A los editores; por favor, no trate de hacer que el pseudo código SQL en bloques de código, simplemente no funciona, ya que el comentario se basa en NEGRITA.
    • A los editores (de nuevo) por favor, no agregue espurias comillas a través de la seudo código, que NO ayuda a la comprensión.
  3. 16

    Usted necesita para hacer una de estas dos opciones:

    1. Incluir el componente de tiempo en su between condición: ... where created_at between '2013-05-01 00:00:00' and '2013-05-01 23:59:59' (no recomendado… ver último párrafo)
    2. Uso de las desigualdades en lugar de between. Observe que, a continuación, tendrá que añadir un día para el segundo valor: ... where (created_at >= '2013-05-01' and created_at < '2013-05-02')

    Mi preferencia personal es la segunda opción. También, Aaron Bertrand ha una explicación muy clara sobre por qué debería ser utilizado.

    • +1 por 2. Pero de -1 a 1. Este fin de día hack es completamente fiable y una mala idea.
    • Yo también prefiero la opción 2 (yo lo uso con frecuencia). Pero, ¿por qué usted dice que la opción 1 es «para nada confiable»?
    • por favor, lea esta en completo. Usted nunca debe utilizar BETWEEN por rango de fecha, las consultas que incluyen el tiempo; demasiado puede ir mal.
  4. 6

    Me parece que la mejor solución para la comparación de un campo datetime en un campo de fecha es el siguiente:

    DECLARE @StartDate DATE = '5/1/2013', 
            @EndDate   DATE = '5/1/2013' 
    
    SELECT * 
    FROM   cases 
    WHERE  Datediff(day, created_at, @StartDate) <= 0 
           AND Datediff(day, created_at, @EndDate) >= 0 

    Esto es equivalente a un integrador entre la declaración, ya que incluye tanto la fecha de inicio y fin, así como aquellas que caen entre.

  5. 2
    cast(created_at as date)

    Que sólo funcionará en 2008 y las nuevas versiones de SQL Server

    Si usted está utilizando la versión anterior, a continuación, utilizar

    convert(varchar, created_at, 101)
    • convert(varchar, created_at, 101) resultado es como dd/MM/yyyy y OP son las cadenas de caracteres yyyy-MM-dd, creo que esta respuesta no va a funcionar ;).
  6. 1

    Puede utilizar el date() función que se va a extraer de la fecha de datetime y dar el resultado como integradora fecha:

    SELECT * FROM Cases WHERE date(created_at)='2013-05-01' AND '2013-05-01'
  7. 0

    Dyamic la fecha ENTRE el sql de la consulta

    var startDate = '2019-08-22';
    var Enddate = '2019-10-22'
         let sql = "SELECT * FROM Cases WHERE created_at BETWEEN '?' AND '?'";
         const users = await mysql.query( sql, [startDate, Enddate]);

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea