SQL BETWEEN: rangos inclusivos de número y fecha
SQL BETWEEN filtra filas cuyo valor de columna cae dentro de un rango especificado, incluyendo ambos extremos. Reemplaza un par de comparaciones >= y <= con un único predicado, lo que mantiene más cortas las cláusulas WHERE cuando el rango es inclusivo. BETWEEN funciona con números, fechas y texto, aunque los rangos de fechas requieren cuidado extra con los componentes de tiempo.
Ejemplo de SQL BETWEEN para filtrar rangos
Salida:
La salida aparecerá aquí...
Salida:
+----------+-------+------------+
| customer | total | placed |
+----------+-------+------------+
| Ben | 120.5 | 2026-02-15 |
| Cara | 89.99 | 2026-02-20 |
+----------+-------+------------+
2 row(s)
Cómo funciona este ejemplo
CREATE TABLEeINSERTpreparan una tablaorderscon cuatro filas que cubren distintos totales y fechas.WHERE total BETWEEN 50 AND 150conserva solo las filas dondetotal >= 50 AND total <= 150. Ambos límites se incluyen, así que una fila con exactamente 50 o 150 coincidiría.- Las filas con totales de 45.00 y 200.00 quedan fuera del rango y se excluyen.
x BETWEEN y AND z es equivalente a x >= y AND x <= z. Si cualquiera de los límites es NULL, el predicado se evalúa como desconocido y la fila se filtra.
¿Qué es SQL BETWEEN?
SQL BETWEEN comprueba si un valor cae dentro de un rango inclusivo: column >= low AND column <= high. Para rangos numéricos se lee bien y se comporta de forma predecible. Algunas bases de datos también admiten BETWEEN SYMMETRIC, que invierte los límites cuando vienen en orden inverso.
Errores comunes con SQL BETWEEN
Error: usar BETWEEN para rangos de timestamp.
Incorrecto:
WHERE placed BETWEEN '2026-02-01' AND '2026-02-28'
Correcto:
WHERE placed >= '2026-02-01' AND placed < '2026-03-01'
Por qué: si la columna incluye hora, una fecha final como '2026-02-28' suele coincidir solo con el inicio de ese día. Usa un intervalo semiabierto para cubrir el día completo.
Error: invertir los límites y esperar resultados.
Incorrecto:
WHERE total BETWEEN 150 AND 50
Correcto:
WHERE total BETWEEN 50 AND 150
Por qué: con BETWEEN estándar, el primer límite debe ser el valor menor. Si inviertes los límites, la condición no puede ser verdadera.
BETWEEN vs IN vs operadores de comparación
| Enfoque | Úsalo cuando… |
|---|---|
BETWEEN low AND high | El rango es continuo y ambos extremos son inclusivos |
>= low AND < high | Necesitas un límite superior exclusivo (timestamps, paginación) |
IN (a, b, c) | Los valores son discretos, no un rango continuo |
> low AND < high | Ambos extremos deben ser exclusivos |
Regla: prefiere BETWEEN para rangos numéricos inclusivos. Cambia a comparaciones explícitas cuando un límite deba ser exclusivo, sobre todo con fechas. Usa IN para un conjunto fijo de valores; BETWEEN coincidiría con valores no deseados en los huecos.
Notas de rendimiento
BETWEEN es sargable: el planificador de consultas lo trata como >= AND <= y puede usar un índice B-tree sobre la columna filtrada. Envolver la columna en una función (DATE(col), LOWER(col)) impide el uso del índice; normaliza los límites en su lugar. Los rangos amplios siguen leyendo muchas filas incluso con índice, así que la selectividad importa más que el operador.
FAQ
¿SQL BETWEEN es inclusivo o exclusivo?
BETWEEN es inclusivo en ambos extremos. WHERE x BETWEEN 5 AND 10 devuelve filas donde x es 5, 6, 7, 8, 9 o 10. No hay una variante exclusiva integrada; usa > y < para límites exclusivos.
¿Se puede usar BETWEEN con valores de texto?
Sí. WHERE name BETWEEN 'A' AND 'M' devuelve nombres que se ordenan dentro de ese rango según la intercalación actual. Los resultados dependen de las reglas de intercalación y de la sensibilidad a mayúsculas de la base de datos, así que conviene probar con tu configuración antes de depender de rangos de texto en producción.
¿Por qué BETWEEN omite registros en la fecha final?
Cuando la columna almacena un datetime (fecha + hora), un límite superior como '2026-02-28' suele interpretarse como el inicio de ese día. Cualquier fila posterior del 28 de febrero queda fuera del rango. Usa un intervalo semiabierto (>= start AND < next_day) para cubrir el día completo.