Curso de MySQL
Consulta de datos con SELECT en MySQL: guía completa
Por Víctor Peña · Publicado el

Hola, ¿cómo están? Continuando con el curso de MySQL, llegamos a la sentencia más usada de todas: SELECT.
Hasta ahora escribimos datos. A partir de aquí los leemos, que es el 90 % de lo que hace cualquier aplicación.
¡Empecemos!
La consulta más simple
SELECT * FROM pacientes;
El asterisco significa «todas las columnas».
Es cómodo para explorar, pero no lo uses en tus aplicaciones. Trae columnas que no necesitas, y el día que alguien agregue una columna TEXT pesada, tus consultas se vuelven lentas sin que hayas tocado nada.
Lo correcto es pedir solo lo que vas a usar:
SELECT nombre, apellido, telefono FROM pacientes;
Filtrar con WHERE
SELECT nombre, apellido, fecha_nacimiento
FROM pacientes
WHERE fecha_nacimiento > '2000-01-01';
WHERE es donde ocurre lo interesante, y lo veremos en detalle en la siguiente lección. Por ahora, los básicos:
WHERE estado = 'programada'
WHERE costo > 200
WHERE fecha BETWEEN '2026-04-01' AND '2026-04-30'
WHERE telefono IS NULL
WHERE estado IN ('programada', 'atendida')
Cuidado con NULL
Aquí hay una trampa que sorprende a todo el mundo:
SELECT * FROM pacientes WHERE telefono = NULL; -- no devuelve nada
SELECT * FROM pacientes WHERE telefono IS NULL; -- correcto
NULL significa «desconocido», y nada es igual a lo desconocido, ni siquiera otro desconocido. Por eso = NULL nunca es verdadero.
Usa siempre IS NULL e IS NOT NULL.
Ordenar con ORDER BY
SELECT nombre, apellido FROM pacientes
ORDER BY apellido ASC;
SELECT fecha, costo FROM citas
ORDER BY fecha DESC, hora ASC;
ASC es ascendente y es el valor por defecto; DESC descendente.
Puedes ordenar por varias columnas: en el ejemplo, primero por fecha de más reciente a más antigua, y dentro de cada fecha por hora.
Sin ORDER BY, el orden no está garantizado. Puede parecer que salen ordenadas por id, pero MySQL no lo promete. Si el orden importa, decláralo.
Limitar resultados con LIMIT
SELECT * FROM citas ORDER BY fecha DESC LIMIT 10;
Las 10 más recientes. Y para paginar:
SELECT * FROM citas ORDER BY fecha DESC LIMIT 10 OFFSET 20;
Salta 20 filas y devuelve las 10 siguientes: la tercera página.
Un aviso sobre OFFSET grande: LIMIT 10 OFFSET 100000 obliga a MySQL a recorrer cien mil filas para descartarlas. En tablas grandes se vuelve lentísimo. La alternativa es paginar por el último id visto:
SELECT * FROM citas WHERE id > 100000 ORDER BY id LIMIT 10;
Alias con AS
Renombrar columnas en el resultado:
SELECT
nombre AS nombre_paciente,
apellido AS apellido_paciente,
costo * 1.13 AS total_con_impuesto
FROM citas;
Los alias son imprescindibles cuando calculas algo: sin AS, la columna se llamaría costo * 1.13.
También se usan para las tablas, y ahí se agradecen mucho:
SELECT c.fecha, c.costo
FROM citas AS c
WHERE c.estado = 'programada';
El AS es opcional —FROM citas c funciona igual— y es lo que verás en la mayoría del código.
Eliminar duplicados con DISTINCT
SELECT DISTINCT estado FROM citas;
Devuelve cada estado una sola vez. Útil para saber qué valores existen en una columna.
Con varias columnas, considera la combinación completa como única:
SELECT DISTINCT paciente_id, doctor_id FROM citas;
Concatenar y dar formato
SELECT
CONCAT(nombre, ' ', apellido) AS nombre_completo,
UPPER(apellido) AS apellido_mayus,
DATE_FORMAT(fecha_nacimiento, '%d/%m/%Y') AS nacimiento
FROM pacientes;
Funciones que vas a usar seguido:
| Función | Qué hace |
|---|---|
CONCAT() |
Une textos |
UPPER() / LOWER() |
Mayúsculas / minúsculas |
TRIM() |
Quita espacios sobrantes |
SUBSTRING() |
Extrae parte de un texto |
LENGTH() |
Longitud |
ROUND() |
Redondea |
DATE_FORMAT() |
Da formato a una fecha |
TIMESTAMPDIFF() |
Diferencia entre fechas |
Calcular la edad, por ejemplo:
SELECT
nombre,
TIMESTAMPDIFF(YEAR, fecha_nacimiento, CURDATE()) AS edad
FROM pacientes;
Condiciones dentro del SELECT
CASE permite devolver valores distintos según la fila:
SELECT
nombre,
costo,
CASE
WHEN costo >= 300 THEN 'Alto'
WHEN costo >= 200 THEN 'Medio'
ELSE 'Bajo'
END AS rango_costo
FROM citas;
Y IF() para casos simples de dos opciones:
SELECT nombre, IF(telefono IS NULL, 'Sin teléfono', telefono) AS contacto
FROM pacientes;
Existe también IFNULL(), específica para eso:
SELECT nombre, IFNULL(telefono, 'Sin teléfono') AS contacto FROM pacientes;
El orden de ejecución
Este concepto explica muchos errores, así que vale la pena entenderlo.
El orden en que escribes una consulta:
SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
El orden en que MySQL la ejecuta es distinto:
FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT
Fíjate en que SELECT se ejecuta casi al final. De ahí se deriva algo práctico:
-- Falla: el alias todavía no existe cuando se evalúa el WHERE
SELECT costo * 1.13 AS total FROM citas WHERE total > 300;
-- Funciona: ORDER BY sí se ejecuta después del SELECT
SELECT costo * 1.13 AS total FROM citas ORDER BY total DESC;
Puedes usar un alias en ORDER BY pero no en WHERE. Ahora sabes por qué.
Consultas sobre nuestro sistema
Con los datos que insertamos, prueba estas:
-- Pacientes ordenados por apellido
SELECT nombre, apellido, telefono
FROM pacientes
ORDER BY apellido;
-- Citas de abril, de la más cara a la más barata
SELECT fecha, hora, costo, estado
FROM citas
WHERE fecha BETWEEN '2026-04-01' AND '2026-04-30'
ORDER BY costo DESC;
-- Las tres citas más próximas que siguen programadas
SELECT fecha, hora, costo
FROM citas
WHERE estado = 'programada' AND fecha >= CURDATE()
ORDER BY fecha, hora
LIMIT 3;
-- Pacientes menores de edad
SELECT
CONCAT(nombre, ' ', apellido) AS paciente,
TIMESTAMPDIFF(YEAR, fecha_nacimiento, CURDATE()) AS edad
FROM pacientes
WHERE TIMESTAMPDIFF(YEAR, fecha_nacimiento, CURDATE()) < 18;
Buenas prácticas
- Nombra las columnas, no uses
SELECT *en producción. LIMITal explorar una tabla que no conoces. UnSELECT *sobre millones de filas puede colgar la herramienta.ORDER BYexplícito si el orden importa.IS NULL, nunca= NULL.- Alias claros en columnas calculadas.
Errores comunes
WHERE telefono = NULL.- Usar un alias del
SELECTdentro delWHERE. - Asumir un orden sin
ORDER BY. SELECT *en una aplicación, trayendo columnas pesadas sin necesidad.OFFSETenorme para paginar tablas grandes.
Para cerrar
SELECT es la sentencia que más vas a escribir en tu vida como desarrollador. Lo básico se aprende en una tarde; lo que marca diferencia es entender el orden de ejecución y el comportamiento de NULL.
En la siguiente lección profundizamos en los operadores del WHERE, que es donde una consulta se vuelve precisa.
Saludos y éxitos.
Norvic Software
Desarrollamos el software que tu empresa necesita
Somos una fábrica de software en Bolivia. Construimos sistemas a medida y aplicaciones móviles, y llevamos Inteligencia Artificial a las empresas que ya tienen un sistema funcionando.
- Chatbots con Inteligencia Artificial
- Creación de agentes de IA
- Integración de IA en tus sistemas
- Desarrollo de software a medida
- Aplicaciones móviles iOS y Android
- Consultoría y asesoramiento técnico
Cotización sin costo · Respuesta directa por WhatsApp