Ejercicios prácticos sobre la tabla empleados (MySQL 8).
Copia y pega en MySQL (bloque copiable):
-- Crear base de datos y usarla CREATE DATABASE empresa; USE empresa; -- (Recrear tabla si existía) DROP TABLE IF EXISTS empleados; -- Tabla de referencia CREATE TABLE empleados ( id_empleado INT PRIMARY KEY, nombre VARCHAR(100) NOT NULL, edad INT, salario DECIMAL(10,2), departamento VARCHAR(50), fecha_alta DATE ); -- Datos de ejemplo (10 filas, varios departamentos) INSERT INTO empleados (id_empleado, nombre, edad, salario, departamento, fecha_alta) VALUES (1, 'Ana Torres',28, 2100.00, 'Marketing','2023-02-10'), (2, 'Luis Pérez',35, 2800.50, 'Ventas','2022-06-15'), (3, 'Marta Gómez',41, 3200.00,'IT','2021-09-01'), (4, 'Carlos Ruiz',24, 1800.00, 'Marketing','2024-01-20'), (5, 'Sofía López',30, 2500.75, 'RRHH','2020-11-12'), (6, 'Javier Díaz',45, 4000.00, 'Dirección','2019-03-08'), (7, 'Elena Martín',29, 2300.00, 'Ventas','2023-07-25'), (8, 'Pablo Ortega',38, 2950.00, 'IT','2022-02-01'), (9, 'Nuria Santos',33, 2700.00, 'RRHH','2021-12-05'), (10, 'Diego Navarro',27, 1900.00, 'Soporte','2024-05-19'); -- Verifica SELECT * FROM empleados;
Empleado (alias de nombre) y SalarioAnual = salario × 12.
Alias (AS) mejora la legibilidad del resultado y el consumo en informes. La operación es fila a fila. Si salario es NULL, el producto también lo será. Para evitarlo: COALESCE(salario,0)*12.
Buena práctica: calcula con precisión y redondea solo al presentar.
Nombre, edad y Edad_5 = edad + 5.
Las columnas derivadas no se persisten: se calculan al ejecutar la consulta. Ten en cuenta la propagación de NULL. Para valores por defecto, usa COALESCE.
SalarioNeto con retención del 15% (× 0.85).
Para finanzas, DECIMAL ofrece precisión decimal. Si la retención cambia, evita “números mágicos”: guárdala en una tabla de parámetros.
Concatenación: Etiqueta = nombre + ‘ – ‘ + departamento.
CONCAT devuelve cadena vacía con NULL; CONCAT_WS omite nulos y gestiona el separador.
Salario mensual con 2 decimales.
Redondea en presentación (no en cálculo intermedio) para evitar errores acumulados.
Primas: Prima5 = ×1.05, Prima10 = ×1.10.
Parametriza los porcentajes en una tabla si cambian con frecuencia. Evita “números mágicos” en consultas.
Total de empleados con COUNT(*).
Diferencia: COUNT(*) cuenta filas; COUNT(col) ignora nulos de col. No requiere GROUP BY para un único escalar global.
Salario medio global con AVG.
AVG ignora nulos. Si quieres tratarlos como 0, usa AVG(COALESCE(salario,0)) y deja constancia del criterio.
Salario mínimo y máximo.
Para conocer quién cobra el mínimo/máximo, combina con ORDER BY salario ASC/DESC LIMIT 1 o funciones ventana.
Edad media por departamento.
Recuerda: WHERE filtra antes de agrupar; HAVING filtra después, sobre agregados (p. ej., HAVING AVG(edad)>35).
Empleados por departamento (de mayor a menor).
Si necesitas incluir departamentos sin empleados, requerirás una tabla departamentos y LEFT JOIN (fuera de esta píldora).
Masa salarial por departamento (SUM).
SUM ignora nulos. Para contar nulos como 0: SUM(COALESCE(salario,0)). Ordenar por masa salarial ayuda a priorizar decisiones de coste.
HAVING (3 ejemplos)Recuerda: WHERE filtra filas antes de agrupar; HAVING filtra los grupos resultantes.
1) Departamentos con 3 o más empleados.
SELECT departamento, COUNT(*) AS Total FROM empleados GROUP BY departamento HAVING Total >= 3 ORDER BY Total DESC;
Agrupamos por departamento y filtramos los grupos con HAVING según el agregado COUNT(*). En MySQL puedes referirte al alias Total dentro de HAVING.
2) Departamentos con salario medio > 2700 y edad media < 35.
SELECT departamento, ROUND(AVG(salario), 2) AS SalarioMedio, ROUND(AVG(edad), 1) AS EdadMedia FROM empleados GROUP BY departamento HAVING SalarioMedio > 2700 AND EdadMedia < 35 ORDER BY SalarioMedio DESC;
Combinamos condiciones sobre agregados. WHERE no sirve con AVG porque actúa antes de agrupar; HAVING filtra los grupos ya calculados.
3) Departamentos con masa salarial > 6000 y al menos un salario ≥ 3000.
SELECT departamento, ROUND(SUM(salario), 2) AS MasaSalarial, MAX(salario) AS SalarioMax FROM empleados GROUP BY departamento HAVING MasaSalarial > 6000 AND SalarioMax >= 3000 ORDER BY MasaSalarial DESC;
“Al menos uno cumple” se expresa con MAX(salario) ≥ 3000 o SUM(salario >= 3000) >= 1 (TRUE=1 en MySQL). Ambas son válidas en HAVING.