sql >> Base de Datos >  >> RDS >> Database

SQL BETWEEN-Consejos inteligentes para buscar un rango de valores

SQL BETWEEN es un operador que se usa para especificar un rango de valores para probar. El valor devuelto puede ser inclusivo o estar dentro del rango. O puede estar fuera del rango si agrega el operador NOT antes. Funciona para fechas, fechas con hora, números y cadenas.

Puede usarlo en cláusulas WHERE para lo siguiente:

  • SELECCIONAR,
  • INSERTAR (con SELECCIONAR)
  • ACTUALIZAR,
  • y ELIMINAR.

También funciona para cláusulas HAVING junto con GROUP BY.

Pero si no tiene cuidado, SQL BETWEEN puede volverlo loco al usarlo, especialmente con fechas con tiempo.

Sin embargo, no te preocupes. Tenemos ejemplos para lidiar con los errores al usar SQL BETWEEN. Pero antes de eso, los datos de muestra que usé procedían de NOAA . Puede solicitarles datos meteorológicos de forma gratuita. Usé los registros de temperatura por hora para los Estados Unidos en el año 2010. Luego, importé los datos CSV a SQL Server usando SQL Server Management Studio. Cambié el nombre de las columnas y agregué un índice no agrupado.

Comencemos.

Uso de SQL BETWEEN con fechas y horas

Este debe ser el elemento más buscado cuando se trata de SQL BETWEEN. Usaremos ejemplos para explicar cómo funciona.

Sugerencia n.º 1:para las columnas DATETIME, especifique tanto la fecha como la hora

USO INCORRECTO

Comencemos con el uso incorrecto para enfatizar este punto. El siguiente uso de BETWEEN con columnas DATETIME dará resultados inesperados.

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ENTRE '01/01/2010' Y '01/02/2010'Y Latitud =41,995Y Longitud =-87,9336; 


La consulta devuelve datos de 2 días desde una estación meteorológica cerca del Aeropuerto Internacional O'Hare en Chicago. Puede notar el rango entre un valor más bajo (01/01/2010) y un valor más alto (02/01/2010). Aquí está el conjunto de resultados en la Figura 1.

Figura 1 . Conjunto de resultados de una consulta usando SQL ENTRE 2 fechas.

Pero, ¿dónde está el problema?

Se supone que es un registro por hora durante 2 días. Por eso, el conjunto de resultados debe tener 48 registros. Pero observe que son solo 24. El problema radica en el elemento de tiempo de DateHour columna. Cuando no especifica la hora en una columna DATETIME, asume 00:00 o 12:00 AM. Además, tenga en cuenta que los datos comenzaron el 1 de enero de 2010 a la 01:00 a. m., no a las 00:00 a. m.

Entonces, internamente, SQL Server usó DateHour ENTRE ’01/01/2010 00:00:00.000′ Y ’01/02/2010 00:00:00.000′ . ¿Cómo lo sabemos?

LA FECHA ES REALMENTE UNA CADENA

Así es.

Los valores de fecha entre comillas simples no son realmente fechas sino cadenas . SQL Server usa la conversión implícita para convertir la cadena a DATETIME. Después de la conversión, la parte de la hora se agregará a la fecha.

Inspeccionemos con Incluir plan de ejecución real . Presiona Ctrl-M en SQL Server Management Studio, luego vuelva a ejecutar el ejemplo anterior.

Cuando aparezca el Plan de ejecución, haga clic con el botón derecho en Búsqueda de índice operador y seleccione Propiedades . Consulte la figura 2.

Figura 2 . Conversión implícita de una cadena a DATETIME. Está oculto en el Plan de Ejecución de una consulta usando BETWEEN.

Luego expanda Buscar predicados . Las partes encuadradas de la Figura 2 muestran la conversión implícita de las 2 cadenas a DATETIME. Dado que la conversión implícita se realiza internamente , los novatos se confunden por qué no se cumplen sus expectativas en el conjunto de resultados.

USO CORRECTO

El siguiente ejemplo devolverá los registros por hora entre las 8:00 a. m. y las 12:00 p. m. del 2 de enero de 2010.

SELECT * FROM TemperatureDataWHERE FechaHora ENTRE '02/01/2010 08:00' Y '02/01/2010 12:00'Y Latitud =41,995Y Longitud =-87,9336; 


Debe especificar la porción de tiempo, especialmente cuando las fechas son las mismas. O sus resultados esperados no sucederán.

Para devolver los registros de todo el día, esto no funcionará:

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ='06/01/2010' AND Latitude =41.995 AND Longitud =-87.9336; 


Solo devolverá 1 registro:el del 1 de junio de 2010 a las 00:00. Pero usando BETWEEN con los tiempos especificados, puede devolver el registro de cada hora para todo el día. Vea el siguiente ejemplo.

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ENTRE '01/06/2010 00:00' Y '01/06/2010 23:00'Y Latitud =41,995Y Longitud =-87,9336; 


Tenga en cuenta que especifiqué solo hasta las 23:00. Si sus datos usan cualquier hora del día, use 23:59 o 11:59 p. m. en el valor más alto del rango. Especifique los segundos también si los necesita.

Sugerencia n.º 2:tenga en cuenta el tipo de datos FECHA

Si no necesita la porción de tiempo, considere el tipo de datos FECHA en su lugar. Y evitará los problemas mencionados anteriormente.

SQL ENTRE con Números

Pasemos a los números.

Consejo n.° 3:incluya la parte decimal para valores no enteros

SELECT DateHour,[Hourly_Heating_Grade_Hours]FROM TemperatureDataWHERE DateHour ENTRE '01/06/2010' Y '06/5/2010 23:00' AND [Hourly_Heating_Grade_Hours] ENTRE 5,0 Y 7,0 Y Latitud =41,995 Y Longitud =- 87.9336; 


Tenga en cuenta la adición de otra condición que involucra números. Los resultados se limitarán aún más a 5 y 7 grados.

Cuando utilice los tipos de datos DECIMAL, MONEY o FLOAT, especifique la parte decimal incluso si es cero, como 52,00 o 10,0000. De esta manera, evita la conversión implícita a los tipos de datos DECIMAL, MONEY o FLOAT de destino.

SQL ENTRE con cadenas

Sugerencia n.° 4:para cadenas, el rango se basa en la intercalación

Con cadenas, BETWEEN evalúa los valores según el orden alfabético. 'A' es el menor y 'Z' es el mayor. También puede decir que, en general, la evaluación se basa en la comparación. Porque el inglés no es el único idioma que admite SQL Server. Colección proporciona reglas de clasificación, mayúsculas y minúsculas y distinción de acentos. Usemos AdventureWorks base de datos para este ejemplo. Consulte el código a continuación y el resultado en la Figura 3.

USE AdventureWorksGOSELECT LastName,FirstName,MiddleNameFROM Person.PersonWHERE Lastname ENTRE 'Spanaway' Y 'Splane'ORDER BY LastName; 

Figura 3 . Conjunto de resultados de una consulta usando BETWEEN con cadenas.

El rango cubre el apellido Spanaway . Pero, ¿dónde está Splane? ? No existe en la base de datos. Entonces, el resultado solo llegó hasta Spicer .

Sugerencias SQL BETWEEN para todos los tipos de datos admitidos

Ya sea que esté usando BETWEEN para fechas, números o cadenas, hay cosas comunes que debe tener en cuenta. Esto podría ser de sentido común, pero aún sucede por error. Lea cómo puede suceder esto.

Consejo n.º 5:los valores inicial y final no pueden ser NULL

BETWEEN necesita valores iniciales y finales para el rango. Cada uno debe tener un valor que no sea NULL. Hay un ejemplo con un valor final NULL a continuación.

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ENTRE '01/01/2010' Y NULL; 


Esto puede suceder si llama a la instrucción SELECT desde una aplicación o un procedimiento almacenado y no la validó correctamente.

Consejo n.º 6:el valor inicial no puede ser mayor que el valor final

Tampoco se devolverá nada si ambos valores no son NULL, pero el rango se invierte. He aquí un ejemplo.

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ENTRE '01/30/2010' Y '01/01/2010'; 


Aparte de las fechas, las siguientes expresiones tampoco devolverán un resultado:

  • valor ENTRE 100 Y -200. Porque -200 es menor que 100.
  • trabajo ENTRE 'Zookeeper' Y 'Contador'. Porque 'Z' es mayor que 'A'.

Sugerencia n.º 7:los valores de rango deben ser del mismo tipo de datos

A veces, los controles de la interfaz de usuario tienen resultados inesperados. O simplemente elegimos la propiedad equivocada. Y si no lo comprobamos antes de pasarlo a SQL Server, podría ocurrir una situación como esta:

SELECT DateHour,Hourly_Heating_Degree_HoursFROM TemperatureDataWHERE DateHour ENTRE '01/06/2010' Y 'Sábado, 5 de junio de 2010'Y Latitud =41,995Y Longitud =-87,9336; 

Se producirá un error de conversión de una cadena de caracteres a una fecha.

Por lo tanto, la lección de los consejos n.° 5 a n.° 7 es validar los valores inicial y final del rango. .

Sugerencia n.º 8:utilice NO ENTRE para excluir valores

Considere otro ejemplo.

23 :00'Y FechaHora NO ENTRE '01/05/2010 00:00' Y '31/05/2010 23:00'Y Latitud =41,995Y Longitud =-87,9336GRUPO POR MES(FechaHora);


Esto devolverá el promedio mensual de enero a junio, pero excluirá mayo. La exclusión de los registros de mayo de 2010 es posible gracias a NOT BETWEEN. Aquí está el conjunto de resultados en la Figura 4.

Figura 4 . Conjunto de resultados de una consulta usando NOT BETWEEN.

SQL BETWEEN comparado con otros operadores

Consejo n.º 9:use IN si necesita una lista y no un rango

El operador IN determina si un valor coincide con cualquier valor en una lista o subconsulta. Mientras tanto, el uso de NOT IN comprueba si un valor no coincide.

Los operadores BETWEEN e IN filtran datos en función de varios valores. Pero la diferencia radica en el conjunto de valores que se igualan. BETWEEN usa un rango. Pero IN usa valores separados por comas en una lista o filas en una subconsulta.

Consulte el ejemplo a continuación.

SELECT DateHour,[Hourly_Heating_Grade_Hours]FROM TemperatureDataWHERE DateHour BENTWEEN '01/06/2010' AND '06/5/2010 23:00' AND [Hourly_Heating_Grade_Hours] IN (5.2, 6, 7, 3.7) AND Latitude =41.995Y Longitud =-87.9336; 


Mire la lista de valores utilizados por IN. No es necesario que sea una lista de valores crecientes. El último valor de la lista (3.7) también es el menor entre los números.

Consejo n.º 10:elige entre ENTRE o>=con <=

En tiempo de ejecución, SQL Server convierte BETWEEN en>=con operadores <=. ¿Cómo lo sabemos?

Mira el código a continuación.

SELECT DateHour,AVG(Hourly_Heating_Grade_Hours) AS AverageTempFROM TemperatureDataWHERE DateHour BETWEEN '01/01/2010 08:00' AND '01/01/2010 12:00'GROUP BY DateHour;SELECT DateHour,AVG(Hourly_Heating_Grade_Hours) AS AverageTempFROM TemperatureDataWHERE DateHour>='01/01/2010 08:00' AND DateHour <='01/01/2010 12:00'GROUP BY DateHour; 


Ambas consultas tendrán el mismo conjunto de resultados que el de la Figura 5.

Figura 5 . Conjunto de resultados al usar BETWEEN o>=con <=.

También tienen el mismo plan de ejecución, como se ve en la Figura 6.

Figura 6 . Plan de ejecución de 2 consultas comparando el uso de BETWEEN, y los operadores>=y <=.

Pero aquí está la cosa.

Observe el primer Índice Buscar operador en la Figura 6. Luego, vea el Buscar predicados . ¿Ves la palabra clave BETWEEN? No hay ninguno, ¿verdad? Porque se convierte a>=con operadores <=. Esos son los operadores presentes en Buscar predicados .

Pero hay más.

Si pasa el mouse sobre el segundo Buscar índice operador, verá las mismas propiedades que el primer Búsqueda de índice .

Entonces, parece que el operador BETWEEN es un atajo a>=con operadores <= . Escribirás más si usas este último. Verá que ocurre la misma conversión cuando BETWEEN se usa en números y cadenas.

Al final, depende de usted si usa BETWEEN o los operadores>=y <=. El tiempo de conversión que se tarda en convertir ENTRE es insignificante. Pero si aún no quiere ese tiempo extra e insignificante, use los operadores>=y <=.

Conclusión

SQL BETWEEN es bueno para obtener datos que incluyen el rango. Y no es tan difícil de usar. Incluso los valores DATETIME son manejables con BETWEEN. Solo asegúrese de cubrir la parte del tiempo correctamente. También es equivalente a usar>=con <=. Tú decides cuál prefieres usar.

Puede marcar esta página para obtener SQL ENTRE consejos para fechas, números y cadenas cuando los necesite.

Si tiene algunos trucos para usar BETWEEN que no cubrimos, puede compartirlos con nosotros en la sección de Comentarios. Y si te gusta este artículo, compártelo presionando los botones de las redes sociales.

¡Feliz codificación a todos!