Ejercicios - Gestión de Empleados
Modelo Relacional
erDiagram
EMPLEADO {
int id PK
varchar(9) nif
varchar(100) nombre
varchar(100) apellido
int codigo_departamento FK
}
DEPARTAMENTO {
int id PK
varchar(100) nombre
double presupuesto
}
EMPLEADO ||--o{ DEPARTAMENTO: pertenece
Creación de la bases de datos, tablas e inserts de datos
DROP DATABASE IF EXISTS empleados;
CREATE DATABASE empleados CHARACTER SET utf8mb4;
USE empleados;
CREATE TABLE departamento (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(100) NOT NULL,
presupuesto DOUBLE UNSIGNED NOT NULL,
gastos DOUBLE UNSIGNED NOT NULL
);
CREATE TABLE empleado (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
nif VARCHAR(9) NOT NULL UNIQUE,
nombre VARCHAR(100) NOT NULL,
apellido1 VARCHAR(100) NOT NULL,
apellido2 VARCHAR(100),
id_departamento INT UNSIGNED,
FOREIGN KEY (id_departamento) REFERENCES departamento(id)
);
INSERT INTO departamento VALUES(1, 'Desarrollo', 120000, 6000);
INSERT INTO departamento VALUES(2, 'Sistemas', 150000, 21000);
INSERT INTO departamento VALUES(3, 'Recursos Humanos', 280000, 25000);
INSERT INTO departamento VALUES(4, 'Contabilidad', 110000, 3000);
INSERT INTO departamento VALUES(5, 'I+D', 375000, 380000);
INSERT INTO departamento VALUES(6, 'Proyectos', 0, 0);
INSERT INTO departamento VALUES(7, 'Publicidad', 0, 1000);
INSERT INTO empleado VALUES(1, '32481596F', 'Aarón', 'Rivero', 'Gómez', 1);
INSERT INTO empleado VALUES(2, 'Y5575632D', 'Adela', 'Salas', 'Díaz', 2);
INSERT INTO empleado VALUES(3, 'R6970642B', 'Adolfo', 'Rubio', 'Flores', 3);
INSERT INTO empleado VALUES(4, '77705545E', 'Adrián', 'Suárez', NULL, 4);
INSERT INTO empleado VALUES(5, '17087203C', 'Marcos', 'Loyola', 'Méndez', 5);
INSERT INTO empleado VALUES(6, '38382980M', 'María', 'Santana', 'Moreno', 1);
INSERT INTO empleado VALUES(7, '80576669X', 'Pilar', 'Ruiz', NULL, 2);
INSERT INTO empleado VALUES(8, '71651431Z', 'Pepe', 'Ruiz', 'Santana', 3);
INSERT INTO empleado VALUES(9, '56399183D', 'Juan', 'Gómez', 'López', 2);
INSERT INTO empleado VALUES(10, '46384486H', 'Diego','Flores', 'Salas', 5);
INSERT INTO empleado VALUES(11, '67389283A', 'Marta','Herrera', 'Gil', 1);
INSERT INTO empleado VALUES(12, '41234836R', 'Irene','Salas', 'Flores', NULL);
INSERT INTO empleado VALUES(13, '82635162B', 'Juan Antonio','Sáez', 'Guerrero', NULL);Consultas sobre una tabla
Lista el primer apellido de todos los empleados.
sqlSELECT apellido1 FROM empleadoLista el primer apellido de los empleados eliminando los apellidos que estén repetidos.
sqlSELECT DISTINCT apellido1 FROM empleadoLista todas las columnas de la tabla empleado.
sqlSELECT * FROM empleadoLista el nombre y los apellidos de todos los empleados.
sqlSELECT nombre, apellido1, apellido2 FROM empleadoLista el código de los departamentos de los empleados que aparecen en la tabla empleado.
sqlSELECT codigo_departamento FROM empleadoLista el código de los departamentos de los empleados que aparecen en la tabla empleado, eliminando los códigos que aparecen repetidos.
sqlSELECT DISTINCT codigo_departamento FROM empleadoLista el nombre y apellidos de los empleados en una única columna.
sqlSELECT CONCAT(nombre, ' ', apellido1, ' ', IFNULL(apellido2,'')) AS 'Nombre Completo' FROM empleadoLista el nombre y apellidos de los empleados en una única columna, convirtiendo todos los caracteres en mayúscula.
sqlSELECT UPPER(CONCAT(nombre, ' ', apellido1, ' ', IFNULL(apellido2,''))) AS 'Nombre Completo' FROM empleadoLista el nombre y apellidos de los empleados en una única columna, convirtiendo todos los caracteres en minúscula.
sqlSELECT LOWER(CONCAT(nombre, ' ', apellido1, ' ', IFNULL(apellido2,''))) AS 'Nombre Completo' FROM empleadoLista el código de los empleados junto al nif, pero el nif deberá aparecer en dos columnas, una mostrará únicamente los dígitos del nif y la otra la letra.
sqlSELECT e.codigo, LEFT(e.nif, 8) AS 'Dígitos', RIGHT(e.nif, 1) AS 'Letra' FROM empleado eLista el nombre de cada departamento y el valor del presupuesto actual del que dispone. Para calcular este dato tendrá que restar al valor del presupuesto inicial (columna presupuesto) los gastos que se han generado (columna gastos). Tenga en cuenta que en algunos casos pueden existir valores negativos. Utilice un alias apropiado para la nueva columna columna que está calculando.
sqlSELECT d.nombre, (d.presupuesto - d.gastos) AS 'Presupuesto actual' FROM departamento dLista el nombre de los departamentos y el valor del presupuesto actual ordenado de forma ascendente.
sqlSELECT d.nombre, (d.presupuesto - d.gastos) AS 'Presupuesto' FROM departamento d ORDER BY Presupuesto ASCLista el nombre de todos los departamentos ordenados de forma ascendente.
sqlSELECT d.nombre FROM departamento d ORDER BY 1 ASCLista el nombre de todos los departamentos ordenados de forma descendente.
sqlSELECT d.nombre FROM departamento d ORDER BY 1 DESCLista los apellidos y el nombre de todos los empleados, ordenados de forma alfabética tendiendo en cuenta en primer lugar sus apellidos y luego su nombre.
sqlSELECT e.nombre, e.apellido1, e.apellido2 FROM empleado e ORDER BY 2 ASC, 3 ASC, 1 ASCDevuelve una lista con el nombre y el presupuesto, de los 3 departamentos que tienen mayor presupuesto.
sqlSELECT d.nombre, d.presupuesto FROM departamento d ORDER BY 2 DESC LIMIT 3Devuelve una lista con el nombre y el presupuesto, de los 3 departamentos que tienen menor presupuesto.
sqlSELECT d.nombre, d.presupuesto FROM departamento d ORDER BY 2 ASC LIMIT 3Devuelve una lista con el nombre y el gasto, de los 2 departamentos que tienen mayor gasto.
sqlSELECT d.nombre, d.gastos FROM departamento d ORDER BY 2 DESC LIMIT 2Devuelve una lista con el nombre y el gasto, de los 2 departamentos que tienen menor gasto.
sqlSELECT d.nombre, d.gastos FROM departamento d ORDER BY 2 ASC LIMIT 2Devuelve una lista con 5 filas a partir de la tercera fila de la tabla empleado. La tercera fila se debe incluir en la respuesta. La respuesta debe incluir todas las columnas de la tabla empleado.
sqlSELECT * FROM empleado e LIMIT 2, 5Devuelve una lista con el nombre de los departamentos y el presupuesto, de aquellos que tienen un presupuesto mayor o igual a 150000 euros.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto >= 150000Devuelve una lista con el nombre de los departamentos y el gasto, de aquellos que tienen menos de 5000 euros de gastos.
sqlSELECT d.nombre, d.gastos FROM departamento d WHERE d.gastos < 5000Devuelve una lista con el nombre de los departamentos y el presupuesto, de aquellos que tienen un presupuesto entre 100000 y 200000 euros. Sin utilizar el operador BETWEEN.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto > 100000 AND d.presupuesto < 200000Devuelve una lista con el nombre de los departamentos que no tienen un presupuesto entre 100000 y 200000 euros. Sin utilizar el operador BETWEEN.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto < 100000 OR d.presupuesto > 200000Devuelve una lista con el nombre de los departamentos que tienen un presupuesto entre 100000 y 200000 euros. Utilizando el operador BETWEEN.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto BETWEEN 100000 AND 200000Devuelve una lista con el nombre de los departamentos que no tienen un presupuesto entre 100000 y 200000 euros. Utilizando el operador BETWEEN.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto NOT BETWEEN 100000 AND 200000Devuelve una lista con el nombre de los departamentos, gastos y presupuesto, de quellos departamentos donde los gastos sean mayores que el presupuesto del que disponen.
sqlSELECT d.nombre, d.gastos, d.presupuesto FROM departamento d WHERE d.gastos > d.presupuestoDevuelve una lista con el nombre de los departamentos, gastos y presupuesto, de aquellos departamentos donde los gastos sean menores que el presupuesto del que disponen.
sqlSELECT d.nombre, d.gastos, d.presupuesto FROM departamento d WHERE d.gastos < d.presupuestoDevuelve una lista con el nombre de los departamentos, gastos y presupuesto, de aquellos departamentos donde los gastos sean iguales al presupuesto del que disponen.
sqlSELECT d.nombre, d.gastos, d.presupuesto FROM departamento d WHERE d.gastos = d.presupuestoLista todos los datos de los empleados cuyo segundo apellido sea NULL.
sqlSELECT * FROM empleado e WHERE e.apellido2 IS NULLLista todos los datos de los empleados cuyo segundo apellido no sea NULL.
sqlSELECT * FROM empleado e WHERE e.apellido2 IS NOT NULLLista todos los datos de los empleados cuyo segundo apellido sea López.
sqlSELECT * FROM empleado e WHERE e.apellido2 = 'López'Lista todos los datos de los empleados cuyo segundo apellido sea Díaz o Moreno. Sin utilizar el operador IN.
sqlSELECT * FROM empleado e WHERE e.apellido2 = 'Díaz' OR e.apellido2 = 'Moreno'Lista todos los datos de los empleados cuyo segundo apellido sea Díaz o Moreno. Utilizando el operador IN.
sqlSELECT * FROM empleado e WHERE e.apellido2 IN ('Díaz', 'Moreno')Lista los nombres, apellidos y nif de los empleados que trabajan en el departamento 3.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM empleado e WHERE e.codigo_departamento = 3Lista los nombres, apellidos y nif de los empleados que trabajan en los departamentos 2, 4 o 5.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM empleado e WHERE e.codigo_departamento IN (2, 4, 5)
Consultas multitabla (Composición interna)
Devuelve un listado con los empleados y los datos de los departamentos donde trabaja cada uno.
sqlSELECT * FROM empleado e INNER JOIN departamento d ON e.codigo_departamento = d.codigoDevuelve un listado con los empleados y los datos de los departamentos donde trabaja cada uno. Ordena el resultado, en primer lugar por el nombre del departamento (en orden alfabético) y en segundo lugar por los apellidos y el nombre de los empleados.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif, d.nombre, d.presupuesto, d.gastos FROM empleado e INNER JOIN departamento d ON e.codigo_departamento = d.codigo ORDER BY d.nombre ASC, e.apellido1 ASC, e.apellido2 ASC, e.nombre ASCDevuelve un listado con el código y el nombre del departamento, solamente de aquellos departamentos que tienen empleados.
sqlSELECT DISTINCT d.codigo, d.nombre FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamentoDevuelve un listado con el código, el nombre del departamento y el valor del presupuesto actual del que dispone, solamente de aquellos departamentos que tienen empleados. El valor del presupuesto actual lo puede calcular restando al valor del presupuesto inicial (columna presupuesto) el valor de los gastos que ha generado (columna gastos).
sqlSELECT DISTINCT d.codigo, d.nombre, (d.presupuesto - d.gastos) AS Presupuesto FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamentoDevuelve el nombre del departamento donde trabaja el empleado que tiene el nif 38382980M.
sqlSELECT d.nombre FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamento WHERE e.nif = '38382980M'Devuelve el nombre del departamento donde trabaja el empleado Pepe Ruiz Santana.
sqlSELECT d.nombre FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamento WHERE e.nombre = 'Pepe' AND e.apellido1 = 'Ruíz' AND e.apellido2 = 'Santana'Devuelve un listado con los datos de los empleados que trabajan en el departamento de I+D. Ordena el resultado alfabéticamente.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamento WHERE d.nombre = 'I+D'Devuelve un listado con los datos de los empleados que trabajan en el departamento de Sistemas, Contabilidad o I+D. Ordena el resultado alfabéticamente.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamento WHERE d.nombre IN ('Sistemas', 'Contabilidad', 'I+D') ORDER BY 2 ASC, 3 ASC, 1 ASCDevuelve una lista con el nombre de los empleados que tienen los departamentos que no tienen un presupuesto entre 100000 y 200000 euros.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM departamento d INNER JOIN empleado e ON d.codigo = e.codigo_departamento WHERE d.presupuesto NOT BETWEEN 100000 AND 200000Devuelve un listado con el nombre de los departamentos donde existe algún empleado cuyo segundo apellido sea NULL. Tenga en cuenta que no debe mostrar nombres de departamentos que estén repetidos.
sqlSELECT d.nombre FROM empleado e INNER JOIN departamento d ON d.codigo = e.codigo_departamento WHERE e.apellido2 IS NULL
Consultas multitabla (Composición externa)
Devuelve un listado con todos los empleados junto con los datos de los departamentos donde trabajan. Este listado también debe incluir los empleados que no tienen ningún departamento asociado.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif, d.nombre, d.presupuesto, d.gastos FROM empleado e LEFT JOIN departamento d ON e.codigo_departamento = d.codigoDevuelve un listado donde sólo aparezcan aquellos empleados que no tienen ningún departamento asociado.
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif, d.nombre, d.presupuesto, d.gastos FROM empleado e LEFT JOIN departamento d ON e.codigo_departamento = d.codigo WHERE e.codigo_departamento IS NULLDevuelve un listado donde sólo aparezcan aquellos departamentos que no tienen ningún empleado asociado.
sqlSELECT d.nombre FROM empleado e RIGHT JOIN departamento d ON e.codigo_departamento = d.codigo WHERE e.codigo IS NULLDevuelve un listado con todos los empleados junto con los datos de los departamentos donde trabajan. El listado debe incluir los empleados que no tienen ningún departamento asociado y los departamentos que no tienen ningún empleado asociado. Ordene el listado alfabéticamente por el nombre del departamento.
sqlSELECT * FROM empleado e RIGHT JOIN departamento d ON e.codigo_departamento = d.codigo ORDER BY d.nombre ASCDevuelve un listado con los empleados que no tienen ningún departamento asociado y los departamentos que no tienen ningún empleado asociado. Ordene el listado alfabéticamente por el nombre del departamento.
sqlSELECT d.nombre FROM empleado e RIGHT JOIN departamento d ON e.codigo_departamento = d.codigo WHERE e.codigo_departamento IS NULL UNION SELECT CONCAT(e2.nombre, ' ', e2.apellido1, ' ', e2.apellido2) AS Nombre FROM empleado e2 LEFT JOIN departamento d2 ON e2.codigo_departamento = d2.codigo WHERE e2.codigo_departamento IS NULL ORDER BY nombre ASC
Consultas resumen
Calcula la suma del presupuesto de todos los departamentos.
sqlSELECT SUM(d.presupuesto) AS 'Suma' FROM departamento dCalcula la media del presupuesto de todos los departamentos.
sqlSELECT AVG(d.presupuesto) AS 'Promedio' FROM departamento dCalcula el valor mínimo del presupuesto de todos los departamentos.
sqlSELECT MIN(d.presupuesto) AS 'Presupuesto mínimo' FROM departamento dCalcula el nombre del departamento y el presupuesto que tiene asignado, del departamento con menor presupuesto.
sqlSELECT d.nombre, MIN(d.presupuesto) AS 'Presupuesto mínimo' FROM departamento dCalcula el valor máximo del presupuesto de todos los departamentos.
sqlSELECT MAX(d.presupuesto) AS 'Presupuesto máximo' FROM departamento dCalcula el nombre del departamento y el presupuesto que tiene asignado, del departamento con mayor presupuesto.
sqlSELECT d.nombre, MAX(d.presupuesto) AS 'Presupuesto máximo' FROM departamento dCalcula el número total de empleados que hay en la tabla empleado.
sqlSELECT COUNT(*) FROM empleado eCalcula el número de empleados que no tienen NULL en su segundo apellido.
sqlSELECT COUNT(*) FROM empleado e WHERE e.apellido2 IS NOT NULLCalcula el número de empleados que hay en cada departamento. Tienes que devolver dos columnas, una con el nombre del departamento y otra con el número de empleados que tiene asignados.
sqlSELECT d.nombre, COUNT(*) AS 'Cantidad' FROM empleado e INNER JOIN departamento d ON e.codigo_departamento = d.codigo GROUP BY d.nombreCalcula el nombre de los departamentos que tienen más de 2 empleados. El resultado debe tener dos columnas, una con el nombre del departamento y otra con el número de empleados que tiene asignados.
sqlSELECT d.nombre, COUNT(*) AS 'Cantidad' FROM empleado e INNER JOIN departamento d ON e.codigo_departamento = d.codigo GROUP BY d.nombre HAVING Cantidad > 2Calcula el número de empleados que trabajan en cada uno de los departamentos. El resultado de esta consulta también tiene que incluir aquellos departamentos que no tienen ningún empleado asociado.
sqlSELECT d.nombre, COUNT(e.nombre) AS 'Cantidad' FROM empleado e RIGHT JOIN departamento d ON e.codigo_departamento = d.codigo GROUP BY d.nombreCalcula el número de empleados que trabajan en cada unos de los departamentos que tienen un presupuesto mayor a 200000 euros.
sqlSELECT d.nombre, COUNT(e.nombre) AS 'Cantidad' FROM empleado e RIGHT JOIN departamento d ON e.codigo_departamento = d.codigo WHERE d.presupuesto > 200000 GROUP BY d.nombre
Subconsultas
Con operadores básicos de comparación
Devuelve un listado con todos los empleados que tiene el departamento de Sistemas. (Sin utilizar INNER JOIN).
sqlSELECT e.nombre, e.apellido1, e.apellido2, e.nif FROM empleado e WHERE e.codigo_departamento = (SELECT d.codigo FROM departamento d WHERE d.nombre = 'Sistemas')Devuelve el nombre del departamento con mayor presupuesto y la cantidad que tiene asignada.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto = (SELECT MAX(d.presupuesto) FROM departamento d)Devuelve el nombre del departamento con menor presupuesto y la cantidad que tiene asignada.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto = (SELECT MIN(d.presupuesto) FROM departamento d)
Subconsultas con ALL y ANY
Devuelve el nombre del departamento con mayor presupuesto y la cantidad que tiene asignada. Sin hacer uso de MAX, ORDER BY ni LIMIT.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto >= ALL(SELECT d.presupuesto FROM departamento d)Devuelve el nombre del departamento con menor presupuesto y la cantidad que tiene asignada. Sin hacer uso de MIN, ORDER BY ni LIMIT.
sqlSELECT d.nombre, d.presupuesto FROM departamento d WHERE d.presupuesto <= ALL(SELECT d.presupuesto FROM departamento d)Devuelve los nombres de los departamentos que tienen empleados asociados. (Utilizando ALL o ANY).
sqlSELECT d.nombre FROM departamento d WHERE d.codigo = ANY(SELECT e.codigo_departamento FROM empleado e)Devuelve los nombres de los departamentos que no tienen empleados asociados. (Utilizando ALL o ANY).
sqlSELECT d.nombre FROM departamento d WHERE d.codigo <> ALL(SELECT DISTINCT e.codigo_departamento FROM empleado e WHERE e.codigo_departamento IS NOT NULL)
Subconsultas con IN y NOT IN
Devuelve los nombres de los departamentos que tienen empleados asociados. (Utilizando IN o NOT IN).
sqlSELECT d.nombre FROM departamento d WHERE d.codigo IN (SELECT e.codigo_departamento FROM empleado e)Devuelve los nombres de los departamentos que no tienen empleados asociados. (Utilizando IN o NOT IN).
sqlSELECT d.nombre FROM departamento d WHERE d.codigo NOT IN (SELECT e.codigo_departamento FROM empleado e WHERE e.codigo_departamento IS NOT NULL)
Subconsultas con EXISTS y NOT EXISTS
Devuelve los nombres de los departamentos que tienen empleados asociados. (Utilizando EXISTS o NOT EXISTS).
sqlSELECT d.nombre FROM departamento d WHERE EXISTS (SELECT e.codigo_departamento FROM empleado e WHERE e.codigo_departamento = d.codigo)Devuelve los nombres de los departamentos que tienen empleados asociados. (Utilizando EXISTS o NOT EXISTS).
sqlSELECT d.nombre FROM departamento d WHERE NOT EXISTS (SELECT e.codigo_departamento FROM empleado e WHERE e.codigo_departamento = d.codigo)
