Imagina que curras como analista en una universidad (sí, estamos montando una base de datos para la uni, ¿te acuerdas?). Te han pedido no solo mostrar los estudiantes y sus notas, sino también añadir una columna con la nota máxima del grupo, para comparar fácilmente los resultados. ¿Cómo lo harías? ¡Por supuesto, usando subconsultas en SELECT!
Una subconsulta en SELECT te permite calcular valores justo en el momento de ejecutar la consulta principal. Mola, porque puedes combinar cálculos agregados, filtros complejos e incluso otra colección de datos en una sola consulta.
Bases de las subconsultas en SELECT
Una subconsulta en SELECT funciona tal cual suena: metes el resultado de un SELECT dentro de otro. Así puedes calcular valores extra para cada fila del resultado.
Aquí tienes un ejemplo sencillo. Supón que tenemos una tabla students con esta estructura:
| student_id | name | group_id |
|---|---|---|
| 1 | Linda | 101 |
| 2 | Otto | 102 |
| 3 | Anna | 101 |
Y la tabla grades:
| grade_id | student_id | grade |
|---|---|---|
| 1 | 1 | 5 |
| 2 | 1 | 4 |
| 3 | 2 | 3 |
| 4 | 3 | 5 |
| 5 | 3 | 4 |
Ejemplo 1: Añadir la nota máxima del grupo
Objetivo: mostrar los nombres de los estudiantes, sus notas y la nota máxima de su grupo, para ver fácilmente cuánto difiere la nota de cada uno respecto al mejor resultado del grupo.
Código SQL:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT MAX(grade) -- esta consulta devuelve un solo valor
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS max_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
¿Qué pasa aquí?
- Para cada estudiante pillamos su nombre y nota (
s.name,g.grade). SELECT MAX(grade)— es la subconsulta que devuelve la nota máxima dentro del grupo del estudiante.- La subconsulta se ejecuta para cada fila de la consulta principal y usa la condición
WHERE students.group_id = s.group_idpara limitar la selección a un solo grupo.
Ejemplo 2: Nota media del grupo
¿Quieres ser aún más útil para los analistas? Añadamos al resultado no solo la nota máxima, sino también la nota media del grupo.
Código SQL:
SELECT
s.name AS student_name,
g.grade AS student_grade,
(
SELECT AVG(grade)
FROM grades
INNER JOIN students ON grades.student_id = students.student_id
WHERE students.group_id = s.group_id
) AS avg_group_grade
FROM
students s
INNER JOIN
grades g ON s.student_id = g.student_id;
Ahora:
- En vez de
MAX()usamosAVG()para calcular la nota media del grupo. - ¡Tienes un análisis de datos "en vivo"!
Limitaciones y recomendaciones
Las subconsultas en SELECT son potentes, pero hay que usarlas con cabeza:
- Rendimiento. Cada subconsulta se ejecuta para cada fila de la consulta principal. Esto puede ralentizar la consulta SQL si las tablas son grandes. Por ejemplo, si hay 1000 estudiantes, ¡la subconsulta se ejecuta 1000 veces!
- Índices. Para acelerar este tipo de consultas, es importante indexar bien las columnas que usas en las condiciones
WHEREde la subconsulta. - Legibilidad. Intenta evitar demasiada anidación. Si las subconsultas se vuelven muy complejas, piensa en moverlas a
FROMo crear tablas temporales.
Ejemplos de uso
Vamos a ver algunos casos interesantes más.
Ejemplo 3: Número de cursos de cada estudiante
Mostramos una tabla donde para cada estudiante aparece el número de cursos en los que está matriculado. La tabla enrollments está relacionada con los estudiantes por student_id:
| student_id | course_id |
|---|---|
| 1 | 201 |
| 1 | 202 |
| 2 | 201 |
| 3 | 203 |
Código SQL:
SELECT
s.name AS student_name,
(
SELECT COUNT(*)
FROM enrollments
WHERE enrollments.student_id = s.student_id
) AS course_count
FROM
students s;
Aquí la subconsulta cuenta el número de registros en la tabla enrollments para cada estudiante.
Ejemplo 4: Flag de "sobresaliente" para cada estudiante
Vamos a mostrar si un estudiante es sobresaliente. El criterio: tener todas sus notas en 5.
Código SQL:
SELECT
s.name AS student_name,
(
SELECT CASE
WHEN MIN(g.grade) = 5 THEN 'Sobresaliente'
ELSE 'No sobresaliente'
END
FROM grades g
WHERE g.student_id = s.student_id
) AS status
FROM
students s;
Aquí usamos un CASE anidado para asignar el estado "Sobresaliente" solo a los estudiantes que tienen todas las notas en 5.
Optimización de subconsultas en SELECT
Ya hemos dicho que el rendimiento puede ser un problema. Aquí tienes algunos consejos para mejorarlo:
- Usa índices. Si las subconsultas filtran datos, asegúrate de que las columnas usadas tengan índices.
- Cachea los resultados. A veces es mejor mover las subconsultas a vistas (
VIEW) o tablas temporales. - Menos anidación. No abuses de la anidación si puedes usar un enfoque más simple.
Las subconsultas en SELECT abren un montón de posibilidades para cálculos y análisis de datos. Aunque pueden ser pesadas para el sistema, si las optimizas bien, hacen que SQL sea mucho más expresivo y flexible. Así que no tengas miedo de experimentar y encontrar tus propias formas de mejorar las consultas.
GO TO FULL VERSION