En este artículo, se presentan ejercicios avanzados de SQL enfocados en Oracle Database, cubriendo temas como el orden de ejecución de palabras clave, el manejo de productos cartesianos, la invocación de atributos en consultas y el alcance de subconsultas.
Orden de Ejecución de Palabras Clave en SQL
En SQL, el orden de ejecución de las cláusulas difiere del orden de escritura. Por ejemplo, la cláusula FROM se procesa primero, seguida de JOIN y ON, luego WHERE, GROUP BY, HAVING, SELECT, y finalmente ORDER BY y LIMIT. Esto es crucial para entender el flujo de datos en consultas complejas.
Manejo de Productos Cartesianos y Renombrado de Atributos en Oracle
Al realizar productos cartesianos en Oracle, es necesario renombrar atributos con nombres dpulicados. En lugar de usar AS, se emplea un espacio seguido del nuevo nombre. Por ejemplo, para seleccionar nombres de estudiantes y cursos:
SELECT alumno.nombre AS nombre_alumno, curso.nombre AS nombre_curso
FROM alumno, curso;
Aquí, se renombran los atributos para evitar ambigüedades en el resultado del producto cartesiano.
Invocación de Atributos en Relaciones SQL
En consultas SQL que involucran uniones o productos cartesianos, los atributos se pueden invocar mediante el nombre de la relación seguido de un punto y el atributo. Por ejemplo, en una consulta con empleados y gerentes:
SELECT e.id_empleado, e.nombre_persona
FROM empleado e
JOIN gestion g ON e.id_empleado = g.id_empleado
WHERE EXISTS (
SELECT 1
FROM empleado
WHERE g.id_gerente = id_empleado AND e.ciudad = ciudad AND e.calle = calle
)
Esto permite acceder a atributos de relaciones anidadas sin conflictos de nombres, incluso después de operaciones de unión.
Alcance de Subconsultas en SQL
Las subconsultas pueden alterar el alcance de funciones de agregación. Por ejemplo, en una cláusula HAVING con una subconsulta, el alcance de AVG puede cambiar al conjunto completo de datos en lugar de los grupos. Es importante estructurar las subconsultas correctamente para evitar resultados inesperados.
Ejercicios de Práctica
A continuación se presentan ejercicios basados en esquemas de bases de datos comunes. Se asume que las tablas tienen claves primarias subrayadas.
Ejercicio 3.9
a. Encontrar el ID, nombre y ciudad de residencia de cada empleado que trabaja en "Banco Corporación Primera".
SELECT id_empleado, nombre_persona, ciudad
FROM empleado, trabajo
WHERE empleado.id_empleado = trabajo.id_empleado
AND nombre_empresa = 'Banco Corporación Primera';
b. Encontrar empleados que trabajan en "Banco Corporación Primera" con salario mayor a 10000.
SELECT id_empleado, nombre_persona, ciudad
FROM empleado, trabajo
WHERE empleado.id_empleado = trabajo.id_empleado
AND nombre_empresa = 'Banco Corporación Primera'
AND salario > 10000;
c. Encontrar IDs de empleados que no trabajan en "Banco Corporación Primera" (dos métodos).
Método 1: Usando MINUS
(SELECT id_empleado FROM empleado)
MINUS
(SELECT id_empleado FROM empleado, trabajo
WHERE empleado.id_empleado = trabajo.id_empleado
AND nombre_empresa = 'Banco Corporación Primera');
Método 2: Usando NOT IN
SELECT id_empleado
FROM empleado
WHERE id_empleado NOT IN (
SELECT id_empleado
FROM trabajo
WHERE nombre_empresa = 'Banco Corporación Primera'
);
d. Encontrar IDs de empleados con salario mayor al máximo salario en "Banco Pequeño Corporación".
SELECT id_empleado
FROM trabajo
WHERE salario > (
SELECT MAX(salario)
FROM trabajo
WHERE nombre_empresa = 'Banco Pequeño Corporación'
);
e. Encontrar empresas ubicadas en la misma ciudad que "Banco Pequeño Corporación" (asumiendo que empresa_nombre es clave primaria).
SELECT nombre_empresa
FROM empresa
WHERE ciudad = (
SELECT ciudad
FROM empresa
WHERE nombre_empresa = 'Banco Pequeño Corporación'
);
f. Encontrar el nombre de la empresa con más empleados (o múltiples si hay empate).
SELECT nombre_empresa
FROM trabajo
GROUP BY nombre_empresa
HAVING COUNT(id_empleado) > ALL (
SELECT COUNT(id_empleado)
FROM trabajo
GROUP BY nombre_empresa
);
g. Encontrar empresas cuyo salario promedio sea mayor que el de "Banco Corporación Primera".
SELECT nombre_empresa
FROM trabajo
GROUP BY nombre_empresa
HAVING AVG(salario) > (
SELECT AVG(salario)
FROM trabajo
WHERE nombre_empresa = 'Banco Corporación Primera'
);
Ejercicio 3.10
a. Actualizar la ciudad de residencia del empleado con ID "12345" a "Newtown".
UPDATE empleado
SET ciudad = 'Newtown'
WHERE id_empleado = '12345';
b. Aumentar el salario de los gerentes en "Banco Corporación Primera": 10% si el salario es menor a 100000, y 3% si es mayor. El orden de las actualizaciones es crucial para evitar aplicaciones múltiples.
UPDATE trabajo AS T
SET T.salario = T.salario * 1.03
WHERE T.id_empleado IN (
SELECT id_empleado FROM gestion
)
AND T.salario > 100000
AND T.nombre_empresa = 'Banco Corporación Primera';
UPDATE trabajo AS T
SET T.salario = T.salario * 1.1
WHERE T.id_empleado IN (
SELECT id_empleado FROM gestion
)
AND T.salario <= 100000
AND T.nombre_empresa = 'Banco Corporación Primera';
Ejercicio 3.16
a. Encontrar ID y nombre de empleados que trbaajan en la misma ciudad donde residen.
SELECT id_empleado, nombre_persona
FROM empleado, trabajo, empresa
WHERE empleado.id_empleado = trabajo.id_empleado
AND trabajo.nombre_empresa = empresa.nombre_empresa
AND empleado.ciudad = empresa.ciudad;
b. Encontrar ID y nombre de empleados que viven en la misma ciudad y calle que su gerente.
SELECT e.id_empleado, e.nombre_persona
FROM empleado e
JOIN gestion g ON e.id_empleado = g.id_empleado
WHERE EXISTS (
SELECT 1
FROM empleado
WHERE g.id_gerente = id_empleado
AND e.ciudad = ciudad
AND e.calle = calle
);
c. Encontrar empleados con salario mayor al promedio de su empresa.
SELECT id_empleado, nombre_persona
FROM trabajo t, empleado e
WHERE t.id_empleado = e.id_empleado
AND salario > (
SELECT AVG(salario)
FROM trabajo s
WHERE t.nombre_empresa = s.nombre_empresa
);
d. Encontrar la empresa con la suma total de salarios mínima.
SELECT nombre_empresa
FROM trabajo
GROUP BY nombre_empresa
HAVING SUM(salario) < ALL (
SELECT SUM(salario)
FROM trabajo
GROUP BY nombre_empresa
);