Ejercicios resueltos de SQL EJERCICIO TRABAJADORES. Estudiando el funcionamiento resumido de una empresa de servicios obtenemos la tabla Empleados y la tabla Trabajos relacionados según el Diseño Conceptual. 1:N (1,N) EMPLEADOS Realizan (0:N) TRABAJOS Vemos dos entidades relacionadas del tipo 1:N, la parte de uno es la tabla principal pues un empleado puede realizar muchos trabajos. La parte N son los Trabajos de ese empleado. La Cardinalidad (0,N) indica que pueden existir empleados sin trabajos asignados. La Cardinalidad (1,N) indica que deben existir empleados para poder asignarles trabajos, es decir, primero creamos los registros de empleados y luego les asignamos trabajos. Pueden existir empleados sin trabajos, pero no trabajos sin empleados. La tabla Trabajos contiene los trabajos realizados por cada empleado para el periodo indicado entre las fechas FechaInicio y FechaFin. Según la teoría de SGBDR debemos crear un campo en TRABAJOS (Tabla hijo) que será clave ajena a la clave primaria de la Tabla EMPLEADOS (Tabla Padre). DISEÑO LÓGICO 2 TABLAS: EMPLEADOS (IdEmpleado, Nombre , Apellido1, Apellido2,Nomina, FechaNacimiento) TRABAJOS(IdTrabajo, FechaInicio, FechaFin, Descripción, Observaciones, IdEmpleado) CLAVE AJENA IdEmpleado de Trabajos a Empleados: Trabajos.IdEmpleado Empleados.IdEmpleado ACTUALIZACIÓN y MODIFICACIÓN DE LA CLAVE AJENA NO PERMITIDA. Antes de crear las tablas debemos crear la base de datos que las contendrá. create database trabajadores; Se crea una tabla inicial para que al conectar no muestre errores pues una base de datos debe contener al menos una tabla. Y si la base de datos Trabajos estuviese vacía mostraría errores al realizar la conexión. Posteriormente ejecutamos las siguientes instrucciones CREATE TABLE para crear las tablas de la base de datos. De esta forma si ejecutamos las instrucciones CREATE TABLE de una a una podremos ver las tablas vacías desde la lista tablas de Expert SQL. 1 Ejercicios resueltos de SQL Tras crear las tablas de la base de datos podemos borrar la tabla TablaEjemplo con DROP TABLE TablaEjemplo; Se debe de crear las estructuras de las 2 tablas definiendo las llaves primarias: create table EMPLEADOS(id_empleado int, nombre varchar(20) Not Null,Apellido1 varchar(20) Not Null,Apellido2 varchar(20) Not Null, Nomina int Not Null,FechaNacimiento datetime); alter table EMPLEADOS add primary key (id_empleado); create table TRABAJOS(id_trabajo int, fechainicio datetime Not Null, Fechafin datetime Not Null, descripcion varchar(30) Not Null, observaciones varchar(50),id_empleado int); alter table TRABAJOS add primary key (id_trabajo); Debemos crear primero la tabla Padre Empleados para poder unirla posteriormente con una clave ajena (Foreingn Key) desde la tabla Trabajos como vemos: alter table TRABAJOS add constraint trabajos_empleados foreign key(id_empleado) references EMPLEADOS(id_empleado); Consideramos que no debemos permitir el borrado ni modificación de la clave primaria relacionada con la clave ajenas con On Delete NO ACTION On Update NO ACTION. DESPUES DE HABER REALIZADO LO ANTERIOR, REALIZAR LAS SIGUIENTES ACCIONES: EJEMPLO: insert into EMPLEADOS(id_empleado,nombre,apellido1,apellido2,nomina,fechanacimiento) values (1,'Pedro', 'López', 'Valle', 2000, '1968/03/19'); 1) Insertar 7 registros en la tabla Empleados con los siguientes datos: 1,'Pedro', 'López', 'Valle', 2000, ’1968/03/19’ 2,'Luis', 'Iglesias', 'González', 3000, ’1996/11/07’ 3,'Alfredo', 'Muñiz', 'Suárez', 1700, ’1979/09/01’ 4,'Sergio', 'Rodríguez', 'Alvarez', 1400, ’1981/04/30’ 5,'Rafael', 'Fuentes', 'Aranda', 1600, ’1966/10/22’ 6,'Luis', 'Fuentes', 'Aranda', 2500, ’1966/01/10’ 7,'Miguel', 'Arias', 'Gómez', 3000, ’1970/01/01’ 2) Insertar 10 registros en la tabla Trabajos para los empleados que se indica: Pedro López: #01/01/1999#,'01/01/2004','Encargado Producción', 'Beneficios según producción' Luis Iglesias 2 Ejercicios resueltos de SQL '1999/10/10', '2001/01/01','Encargado Planta', 'SUELDO FIJO' '2001/01/01', '2002/01/01','Encargado Planta', 'SUELDO FIJO' '2003/01/01', '2004/01/01','Encargado Planta', 'SUELDO FIJO' Rafael Fuentes '1999/01/01', '2001/01/01', 'Peón ', 'SUELDO FIJO' '2001/01/01', '2002/01/01', 'Peón ', 'SUELDO FIJO' '2002/01/01’, '2003/01/01', 'Peón ', 'SUELDO FIJO' Luis Fuentes '1999/01/01', '2011/01/02', 'Encargado ', 'SUELDO FIJO' '2001/01/01', '2003/01/01', 'Encargado ', 'SUELDO FIJO' '2002/01/01', '2005/01/01', 'Encargado ', 'SUELDO FIJO' EJEMPLO: Insert Into Empleados (Nombre, Apellido1, Apellido2, Nomina, FechaNacimiento) Values ('Pedro', 'López', 'Valle', 2000, '1968/03/19') No se incluye el campo IdEmpleado pues es Identity y lo crea la base de datos. 3 Ejercicios resueltos de SQL 3) Escribir las instrucciones para MODIFICAR los registros siguientes: - Cambiar los apellidos de Alfredo pues están al revés. UPDATE Empleados SET apellido1='Suarez',apellido2='Muniz' WHERE Nombre = 'Alfredo'; - Modificar la fecha de nacimiento de los empleados a 1 día más. UPDATE Empleados SET FechaNacimiento = FechaNacimiento + 1; - Modificar el segundo apellido de Miguel a Pérez. UPDATE Empleados SET apellido2='Pérez' WHERE Nombre = 'Miguel'; - Por problemas quitar de la Nomina de todos los trabajadores el 10%. UPDATE Empleados SET Nomina = (Nomina * 0.90); UPDATE Empleados SET Nomina = (Nomina)-(Nomina * 0.10); - Cambiar la descripción del trabajo de Luis Fuentes a Director Jefe. UPDATE trabajos SET Descripción ='DirectorJefe' WHERE Id_empleado = 6; - Modificar el Id_Empleado de código 3 al 9. No se puede pues es un campo id que lo crea la base de datos - Modificar El id_Trabajo de Rafael Fuentes a 12. No se puede pues es un campo id que lo crea la base de datos Como podrías modificar el Id_Empleado de Pedro Rodríguez? Si NO CREAMOS la clave primaria Id_Empleado como IDENTITY(1,1) y la clave ajena References Empleados(Id_Empleado) On Delete CASCADE On Update CASCADE 4) Escribe las sentencias de -SQL para BORRAR los registros siguientes: - Empleado de nombre Luis y Apellido Fuentes: 4 Ejercicios resueltos de SQL DELETE FROM Empleados WHERE Nombre = 'Luis' and apellido1='Fuentes'; Primero tendríamos que eliminar los Trabajos de Luis Fuentes - Empleados de nombre Luis o Sergio: DELETE FROM Empleados WHERE Nombre = 'Luis' OR Nombre = 'Sergio'; SE DEBE UTILIZAR el OR Para que borre Luis O Sergio pues es imposible Que un empleado se llame Luis y Sergio. - Empleados nacidos antes de 1970 pues suponemos que se han jubilado. DELETE FROM Empleados WHERE FechaNacimiento<’1970/01/01’; No se puede porque tienes en otra tabla datos relacionados con esta que es la padre, primero tendríamos que eliminar los otros - Empleados que cobran entre 1500 y 2000 o se llaman de Nombre Alfredo DELETE FROM Empleados WHERE Nomina>1500 and Nomina<2000 OR nombre = 'Alfredo'; 6) SELECT QUE REALICEN LA SIGUIENTE CONSULTAS: Selecciona los Empleados que tienen más de 30 años. De varias formas: SELECT * FROM Empleados WHERE (Date()- FechaNacimiento)>(30*365); UTILIZANDO FUNCIONES INTERNAS DE SQL SELECT * FROM Empleados WHERE Year(Date())-Year(FechaNacimiento)>30; SELECT Nombre, Apellido1, Year(FechaNacimiento) AS Nacido_EL, Year(date()) AS AnyActual,Year(date())- Year(FechaNacimiento)As EDAD_ACTUAL FROM Empleados WHERE (Year(date())- Year(FechaNacimiento))>30; Selecciona Empleados cuyo nombre comienza por P:% significa otro carácter SELECT * FROM Empleados WHERE nombre LIKE 'P%'; Selecciona los Empleados que cobran mas de 2000 ordenados por Nomina. SELECT * FROM Empleados WHERE nomina>2000 ORDER BY Nomina DESC; Que instrucción SQL la Nomina mayor que más cobran los empleados. SELECT max (nomina) FROM Empleados; 5 Ejercicios resueltos de SQL Cual es la media de lo que cobran los Empleados: SELECT avg (nomina) FROM Empleados; Muestra los datos del empleado que más cobra. SELECT * FROM empleados WHERE nomina=(SELECT max(nomina) FROM empleados); Lista los nombres de los Empleados junto a la Fecha Inicio, Fecha Fin y la Descripción del Trabajo. SELECT empleados.nombre,trabajos.FechaInicio, trabajos.FechaFin ,trabajos.descripcion FROM empleados inner join trabajos on empleados.id_empleado=trabajos.id_empleado; ¿Cual es el código IdTrabajo con una Fecha de Inicio Menor?. Es decir el trabajador que más tiempo lleva en la empresa. select id_trabajo, FechaInicio from trabajos WHERE fechainicio=(select min(fechainicio) from trabajos); Cuales son los datos de los Empleados que llevan más tiempo trabajando en la Empresa en un mismo periodo. Es decir, el que más tiempo ha pasado entre FechaInicio y FechaFin: SELECT * FROM Trabajos INNER JOIN Empleados ON Trabajos.Id_Empleado=Empleados.Id_Empleado WHERE (fechafin-fechainicio)=(select max(fechafin-fechainicio) FROM Trabajos); Cuales son los datos de los Empleados que llevan más tiempo trabajando en la Empresa contando todos los periodos. El que más tiempo ha trabajado sumando todos los periodos FechaFin -FechaInicio: SELECT * FROM Trabajos INNER JOIN Empleados ON Trabajos.Id_Empleado=Empleados.Id_Empleado WHERE (fechafin-fechainicio)=(select max(fechafin-fechainicio)FROM Trabajos); ¿Qué empleado tiene 5 letras en el segundo Apellido y este también comienza con ‘V’.IMPORTANTE: Debemos tener en cuenta que al final de cada campo hay caracteres blancos y debemos incluir el % al final del LIKE. SELECT * FROM Empleados WHERE Apellido2 LIKE 'V____%'; Borra los registros de la tabla Empleados sin utilizar la instrucción DELETE ni DROP. La instrucción Drop elimina la tabla de la base de datos. TRUNCATE TABLE Empleados; 6 Ejercicios resueltos de SQL Ejercicio para permitir modificar y borrar datos con clave primaria SIN IDENTITY y borrado y modificación en cascada. Borramos las tablas (Primero trabajos, luego empleados) y creamos las siguientes: CREATE TABLE Empleados (Id_Empleado int PRIMARY KEY,Nombre varchar(20) Not Null,Apellido1 varchar(20) Not Null,Apellido2 varchar(20) Not Null, Nomina Integer Not Null,FechaNacimiento datetime); CREATE TABLE Trabajos (Id_Trabajo int IDENTITY(1,1) PRIMARY KEY,FechaInicio Datetime Not Null,FechaFin Datetime Not Null,Descripción varchar(30) Not Null,Observaciones varchar(50), IdEmpleado Int,Constraint FK_Trabajos_Empleados Foreign Key (IdEmpleado)References Empleados(IdEmpleado) On Delete CASCADE On Update CASCADE); INSERT INTO Empleados VALUES (1,'Pedro', 'López', 'Valle', 2000, ’1968/03/19’); INSERT INTO Empleados VALUES (2, 'Luis', 'Iglesias', 'González', 3000, ’1996/11/07’); INSERT INTO Empleados VALUES (3, 'Alfredo', 'Muñiz', 'Suárez', 1700, ’1979/09/01’); INSERT INTO Empleados VALUES (4, 'Sergio', 'Rodríguez', 'Alvarez', 1400, ’1981/04/30’); INSERT INTO Empleados VALUES (5, 'Rafael', 'Fuentes', 'Aranda', 1600, ’1966/10/22’); INSERT INTO Empleados VALUES (6, 'Luis', 'Fuentes', 'Aranda', 2500, ’1966/01/10’); INSERT INTO Empleados VALUES (7, 'Miguel', 'Arias', 'Gómez', 3000, ’1970/01/01’); INSERTAMOS DATOS EN la tabla Trabajos con el código Id_Empleado adecuado: Pedro López: NOTA: CONSIDERE EL FORMATO DE CAPTURA DE LA FECHA (YYYY/MM/DD) #01/01/1999#,'01/01/2004','Encargado Producción', 'Beneficios según producción' INSERT INTO Trabajos VALUES (#01/01/1999#,'01/01/2004','Encargado Producción', 'Beneficios por producción',1) Luis Iglesias #10/10/1999#, #01/01/2001#,'Encargado Planta', 'SUELDO FIJO' #01/01/2001#, #01/01/2002#,'Encargado Planta', 'SUELDO FIJO' #01/01/2003#, #01/01/2004#,'Encargado Planta', 'SUELDO FIJO' INSERT INTO Trabajos VALUES (#10/10/1999#, #01/01/2001#,'Encargado Planta', 'SUELDO FIJO',2); INSERT INTO Trabajos VALUES (#01/01/2001#, #01/01/2002#,'Encargado Planta', 'SUELDO FIJO'2); INSERT INTO Trabajos VALUES (#01/01/2003#, #01/01/2004#,'Encargado Planta', 'SUELDO FIJO',2); Rafael Fuentes #01/01/1999#, #01/01/2001#, 'Peón ', 'SUELDO FIJO' #01/01/2001#, #01/01/2002#, 'Peón ', 'SUELDO FIJO' #01/01/2002#, #01/01/2003#, 'Peón ', 'SUELDO FIJO' INSERT INTO Trabajos VALUES (#01/01/1999#, #01/01/2001#, 'Peón ', 'SUELDO FIJO',5); INSERT INTO Trabajos VALUES (#01/01/2001#, #01/01/2002#, 'Peón ', 'SUELDO FIJO',5); INSERT INTO Trabajos VALUES (#01/01/2002#, #01/01/2003#, 'Peón ', 'SUELDO FIJO',5); Luis Fuentes 7 Ejercicios resueltos de SQL #01/01/1999#, #01/02/0011#, 'Encargado ', 'SUELDO FIJO' #01/01/2001#, #01/01/2003#, 'Encargado ', 'SUELDO FIJO' #01/01/2002#, #01/01/2005#, 'Encargado ', 'SUELDO FIJO' INSERT INTO Trabajos VALUES (#01/01/1999#, #01/02/0011#, 'Encargado ', 'SUELDO FIJO',6); INSERT INTO Trabajos VALUES (#01/01/2001#, #01/01/2003#, 'Encargado ', 'SUELDO FIJO',6); INSERT INTO Trabajos VALUES (#01/01/2002#, #01/01/2005#, 'Encargado ', 'SUELDO FIJO',6); Ahora repetimos las instrucciones que no hemos podido ejecutar antes: - Modificar el Id_Empleado de código 3 al 9.Primero vemos si existe el SELECT * FROM EMPLEADOS; UPDATE EMPLEADOS SET Id_Empleado=9 WHERE Id_Empleado=3; Ahora se ha podido realizar la modificación. El empleado 3 no tenia trabajos asignados, probamos A cambiar el código Id_Empleado 5, Rafael Fuentes al Id_Empleado 10. - Modificar el IdEmpleado de código 5 al 10. Vemos si existe el 5. SELECT * FROM EMPLEADOS; UPDATE EMPLEADOS SET Id_Empleado=10 WHERE Id_Empleado=5; Ahora se ha podido realizar la modificación. SELECT * FROM EMPLEADOS WHERE IdEmpleado=10; El resultado es: Id_Empleado Nombre Apellido1 Apellido2 ----------- -------------------- -------------------- --------------10 Rafael Fuentes Aranda El empleado 5 tenia 3 trabajos asignados, vemos que su Id_Empleado de la tabla Trabajos ha cambiado también a 10 al tener el On UPDATE CASCADE. SELECT Id_Trabajo,FechaInicio, FechaFin, Id_Empleado Id_Empleado=10; Id_Trabajo ----------5 6 7 - FROM Trabajos WHERE FechaInicio FechaFin Id_Empleado -----------------------------------------------------------------1999-01-01 2004-01-01 10 2001-01-01 2002-01-01 10 2002-01-01 2004-01-01 10 Modificar El id_Trabajo de Rafael Fuentes a 12. Vemos primero sus datos con SELECT. SELECT * FROM EMPLEADOS; UPDATE EMPLEADOS SET Id_Empleado=12 WHERE Nombre= 'Rafael' AND Apellido1='Fuentes'; Ahora se ha podido realizar la modificación. Y también se han modificado sus trabajos. Lo comprobamos con: SELECT * FROM Trabajos; 8 Ejercicios resueltos de SQL Muestra el nombre y Apellidos de cada empleado junto a sus periodos de Trabajo, calculando los años trabajados en cada periodo. SELECT Nombre, Apellido1, Year(FechaInicio) AS AñoInicio, Year(FechaFin) AS AñoFin, Year(FechaFin)Year(FechaInicio) AS AñosTrabajados FROM Trabajos, Empleados WHERE Empleados.Id_Empleado=Trabajos.Id_Empleado; Muestra el nombre y Apellidos de cada empleado junto a sus periodos de Trabajo, calculando los años trabajados en cada periodo. Usando INNER JOIN. SELECT Nombre, Apellido1, Year(FechaInicio) AS AñoInicio, Year(FechaFin) AS AñoFin, Year(FechaFin)-Year(FechaInicio) AS AñosTrabajados FROM Trabajos INNER JOIN Empleados ON Empleados.IdEMpleado=Trabajos.IdEmpleado; Podemos comprobar que el resultado de las dos instrucciones anteriores es el mismo. Escribe las sentencias de SQL para BORRAR los registros siguientes: - Empleado de nombre Luis y Apellido Fuentes: DELETE FROM Empleados WHERE Nombre = 'Luis' and apellido1='Fuentes'; VEMOS QUE SE HA BORRADO EL EMPLEADO Y SUS TRABAJOS. ES CORRECTO. SELECT * FROM EMPLEADOS; - Empleados de nombre Luis o Sergio: DELETE FROM Empleados WHERE Nombre = 'Luis' OR Nombre = 'Sergio'; SE DEBE UTILIZAR el OR Para que borre Luis O Sergio pues es imposible Que un empleado se llame Luis y Sergio. UTILIZAMOS SELECT PARA COMPROBAR SI SE HAN BORRADO. - Empleados nacidos antes de 1970 pues suponemos que se han jubilado. DELETE FROM Empleados WHERE FechaNacimiento<’1970/01/01’; - Empleados que cobran entre 1500 y 2000 o se llaman de Nombre Alfredo DELETE FROM Empleados WHERE Nomina>1500 and Nomina<2000 OR nombre = 'Alfredo'; 9