Consultas y filtros básicos — Parte 2
Consultas avanzadas sobre la base de datos World: filtros de rango con BETWEEN, búsqueda de patrones de texto con LIKE y el comodín %, comprobación de nulos con IS NULL / IS NOT NULL, y una primera subconsulta con IN para cruzar datos entre dos tablas sin usar JOIN.
Resumen rápido
Consultas avanzadas sobre la base de datos World: filtros de rango con BETWEEN, búsqueda de patrones de texto con LIKE y el comodín %, comprobación de nulos con IS NULL / IS NOT NULL, y una primera subconsulta con IN para cruzar datos entre dos tablas sin usar JOIN.
Conceptos clave
Filtra filas cuyo valor esté dentro de un rango inclusivo. BETWEEN 1900 AND 2000 incluye exactamente 1900 y 2000. Equivale a columna >= 1900 AND columna <= 2000.
Operador de comparación para texto que permite patrones con comodines. Se usa en WHERE para buscar filas cuyo texto coincide con un patrón en lugar de un valor exacto.
Representa cualquier secuencia de caracteres (incluida la vacía). NEW% encuentra todo lo que empieza por NEW. %TOWN encuentra todo lo que termina en TOWN. %NEW% encuentra todo lo que contiene NEW en cualquier posición.
Comprueba si el valor de una columna es NULL (ausente). No puede usarse el operador = para comparar con NULL: WHERE columna = NULL siempre devuelve vacío.
Comprueba que el valor de una columna tiene un dato real (no es NULL). Útil para filtrar filas con datos incompletos o desconocidos.
Comprueba si el valor de una columna pertenece a una lista de valores. WHERE continent IN ('Asia', 'Africa') equivale a dos condiciones OR. También acepta una subconsulta como lista.
Consulta SELECT anidada dentro de otra consulta, entre paréntesis. Se evalúa primero y su resultado se usa como entrada de la consulta exterior. Permite cruzar datos entre tablas sin usar JOIN.
Columna que no existe en la tabla sino que se genera al vuelo aplicando una operación matemática a otras columnas. Por ejemplo GNP / Population devuelve el PIB per cápita fila a fila.
Contenido de la clase
BETWEEN: filtrar por rango de valores
BETWEEN simplifica las consultas cuando se quiere filtrar por un intervalo. En lugar de escribir columna >= valor1 AND columna <= valor2, se escribe columna BETWEEN valor1 AND valor2. Ambas formas son equivalentes y producen el mismo resultado.
El rango es siempre inclusivo: los valores extremos se incluyen en el resultado. BETWEEN 1900 AND 2000 devuelve filas donde el valor sea exactamente 1900, exactamente 2000, o cualquier número entre medias.
LIKE y el comodín %: buscar por patrón de texto
WHERE columna = 'valor' solo encuentra coincidencias exactas. LIKE permite buscar por patrón: si el texto empieza por algo, termina por algo, o contiene algo en cualquier posición.
| Patrón | Encuentra… | No encuentra… |
|---|---|---|
| LIKE 'New%' | New York, Newcastle, Newport News | Old New Bridge (no empieza por New) |
| LIKE '%land' | Finland, Iceland, Scotland | Swaziland no (termina en "land" pero mal escrito no) |
| LIKE '%island%' | Rhode Island, Island City | Iceland (empieza por Ice, no contiene "island") |
| LIKE '_rance' | France (un solo carácter antes de rance) | Alliance (dos caracteres antes) |
El comodín _ (guión bajo) representa exactamente un carácter. % representa cero o más caracteres. Se pueden combinar: LIKE 'N_w%' encontraría New, Now, Newcastle…
IS NULL e IS NOT NULL: trabajar con valores ausentes
NULL no es cero, no es texto vacío, no es falso. Es la ausencia de valor. MySQL tiene reglas especiales para NULL: no puede compararse con = ni con <>. La única forma correcta de verificar si algo es NULL es usando IS NULL o IS NOT NULL.
- WHERE IndepYear IS NULL — países sin año de independencia registrado (colonias, territorios, etc.).
- WHERE IndepYear IS NOT NULL — países que sí tienen año de independencia.
- WHERE LifeExpectancy IS NOT NULL AND LifeExpectancy > 75 — países con dato de esperanza de vida Y que supera 75.
IN: comprobar pertenencia a un conjunto
IN comprueba si el valor de una columna aparece en una lista de valores. Es una forma compacta de escribir múltiples condiciones OR sobre la misma columna.
La lista puede ser literal (una serie de valores entre paréntesis separados por coma) o puede ser el resultado de otra consulta SELECT. En este segundo caso se llama subconsulta o subquery.
Columnas calculadas con expresiones matemáticas
SELECT puede incluir expresiones aritméticas (+, -, *, /) que se evalúan fila a fila. El resultado es una columna nueva que no existe en la tabla, generada al vuelo solo para esa consulta.
- GNP / Population — PIB per cápita de cada país.
- Population / 1000000 — población expresada en millones para simplificar la lectura.
- SurfaceArea * 0.386 — convertir km² a millas cuadradas.
Cuando una columna calculada involucra una columna que puede ser NULL o cero en el denominador, hay que protegerse con un WHERE que filtre esos casos antes del cálculo, de lo contrario la consulta puede devolver NULL o un error de división por cero.
Código y ejemplos
BETWEEN: países que se independizaron entre 1900 y 2000
SELECT Name, IndepYear
FROM Country
WHERE IndepYear BETWEEN 1900 AND 2000
ORDER BY IndepYear ASC; Equivale a WHERE IndepYear >= 1900 AND IndepYear <= 2000. Los valores extremos (1900 y 2000) se incluyen en el resultado.
LIKE: ciudades que empiezan por "New"
-- El % después de New significa "cualquier cosa a continuación"
SELECT Name
FROM City
WHERE Name LIKE 'New%';
-- Ciudades que contienen "island" en cualquier posición
SELECT Name
FROM City
WHERE Name LIKE '%island%'; LIKE distingue entre % (cero o más caracteres) y _ (exactamente un carácter). Sin el %, LIKE se comporta igual que =.
IS NULL e IS NOT NULL: datos ausentes
-- Países sin año de independencia registrado
SELECT Name, IndepYear
FROM Country
WHERE IndepYear IS NULL;
-- Países con esperanza de vida registrada y mayor a 75 años
SELECT Name, LifeExpectancy
FROM Country
WHERE LifeExpectancy IS NOT NULL
AND LifeExpectancy > 75
ORDER BY LifeExpectancy DESC; IN con subconsulta: ciudades europeas sin usar JOIN
-- La subconsulta devuelve la lista de códigos de países europeos
-- IN comprueba si el CountryCode de cada ciudad está en esa lista
SELECT Name
FROM City
WHERE CountryCode IN (
SELECT Code
FROM Country
WHERE Continent = 'Europe'
); MySQL evalúa primero la subconsulta (los códigos de países europeos) y luego filtra City con esa lista. Es una alternativa a JOIN que funciona bien para casos sencillos.
Columnas calculadas con alias: PIB per cápita
SELECT
Name AS 'Pais',
Population AS 'Habitantes',
GNP / Population AS 'PIB per capita'
FROM Country
WHERE Population > 0
ORDER BY GNP / Population DESC
LIMIT 15; WHERE Population > 0 evita la división por cero en los países con population = 0 en la base de datos. El alias no puede usarse en el ORDER BY de la misma consulta en MySQL; hay que repetir la expresión.
Consulta combinada: todos los operadores juntos
-- Países asiáticos con más de 10 millones de habitantes
-- ordenados por población descendente
SELECT Name, Continent, Population
FROM Country
WHERE Continent = 'Asia'
AND Population > 10000000
ORDER BY Population DESC
LIMIT 10; Esta consulta combina WHERE con AND, ORDER BY y LIMIT. Sigue exactamente el orden SELECT → FROM → WHERE → ORDER BY → LIMIT.
Errores comunes
Buenas prácticas
Ejercicios
- Busca todos los países cuyo año de independencia esté entre 1800 y 1900 y ordénalos cronológicamente.
- Encuentra todas las ciudades cuyo nombre contenga la palabra "San" en cualquier posición.
- Lista los países que no tienen esperanza de vida registrada (LifeExpectancy IS NULL). ¿Cuántos son?
- Muestra los países de los continentes Asia y Africa usando IN con una lista literal de valores.
- Escribe una subconsulta con IN para encontrar todas las ciudades de países asiáticos (sin usar JOIN).
- Calcula el PIB per cápita (GNP / Population) de los países europeos con más de un millón de habitantes, ordénalos de mayor a menor y muestra solo los 10 primeros. Usa alias descriptivos para todas las columnas.
Checklist final
- Sé usar BETWEEN para rangos numéricos y entiendo que los extremos son inclusivos.
- Puedo construir patrones con LIKE usando % (varios caracteres) y _ (un carácter exacto).
- Entiendo por qué WHERE columna = NULL nunca funciona y uso IS NULL / IS NOT NULL.
- Sé usar IN con una lista de valores literales como alternativa a múltiples OR.
- He escrito al menos una subconsulta con IN para cruzar datos entre dos tablas.
- Puedo crear columnas calculadas con operaciones matemáticas y renombrarlas con AS.
- Combino varios operadores (WHERE, AND, BETWEEN, ORDER BY, LIMIT) en una sola consulta.
¿Has terminado la clase?
Márcala como repasada y vuelve cuando quieras revisarla.