UPTC - Facultad de Ingeniería Especialización en Bases de Datos Introducción Al SQL 2021-1
UPTC - Facultad de Ingeniería Especialización en Bases de Datos Introducción Al SQL 2021-1
1. Mostrar los empleados del departamento donde se encuentra el salario más bajo de
la empresa
Versión 1:
SELECT EMPLOYEE_ID, FIRST_NAME, DEPARTMENT_ID
FROM EMPLOYEES
WHERE DEPARTMENT_ID = (SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE SALARY = (SELECT MIN(salary)
FROM EMPLOYEES));
RESULTADO: 45 rows
Versión 2:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY, DEPARTMENT_ID
FROM EMPLOYEES
WHERE DEPARTMENT_ID = (SELECT DEPARTMENT_ID
FROM EMPLOYEES
WHERE SALARY = (SELECT MIN(SALARY)
FROM EMPLOYEES))
RESULTADO: 45 rows
Versión 3:
SELECT EMPLOYEE_ID, FIRST_NAME, DEPARTMENT_ID
FROM EMPLOYEES
WHERE DEPARTMENT_ID = (SELECT * FROM (SELECT DEPARTMENT_ID
FROM EMPLOYEES
ORDER BY SALARY)
WHERE ROWNUM < 2);
RESULTADO: 45 rows
Versión 1:
SELECT DEPARTMENT_ID, DEPARTMENT_NAME
FROM DEPARTMENTS D
WHERE NOT EXISTS (SELECT * FROM EMPLOYEES E
WHERE E.DEPARTMENT_ID=D.DEPARTMENT_ID);
RESULTADO: 16 rows
Versión 2:
SELECT DEPARTMENT_ID, DEPARTMENT_NAME
FROM DEPARTMENTS
WHERE DEPARTMENT_ID IN (SELECT DEPARTMENT_ID
FROM DEPARTMENTS
MINUS SELECT DEPARTMENT_ID
FROM EMPLOYEES);
RESULTADO: 16 rows
Versión 3:
SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME
FROM DEPARTMENTS D
LEFT OUTER JOIN EMPLOYEES E ON E.DEPARTMENT_ID = D.DEPARTMENT_ID
WHERE E.DEPARTMENT_ID IS NULL;
RESULTADO: 16 rows
Versión 4:
SELECT DEPARTMENT_ID, DEPARTMENT_NAME
FROM DEPARTMENTS WHERE DEPARTMENT_ID IN (SELECT DEPARTMENT_ID
FROM DEPARTMENTS MINUS
SELECT DISTINCT DEPARTMENT_ID
FROM EMPLOYEES);
RESULTADO: 16 rows
Versión 1:
SELECT D.DEPARTMENT_ID, D.DEPARTMENT_NAME, LOC.CITY, (SELECT COUNT(9)
FROM EMPLOYEES E
WHERE E.DEPARTMENT_ID=D.DEPARTMENT_ID) AS "NUMERO
EMPLEADOS", CO.COUNTRY_NAME, R.REGION_NAME
FROM DEPARTMENTS D
INNER JOIN LOCATIONS LOC ON D.LOCATION_ID=LOC.LOCATION_ID
INNER JOIN COUNTRIES CO ON CO.COUNTRY_ID=LOC.COUNTRY_ID
INNER JOIN REGIONS R ON R.REGION_ID=CO.REGION_ID;
RESULTADO: 27 rows.
Versión 2:
SELECT COUNT(EMPLOYEE_ID) NUMERO_EMPLEADOS, DEPARTMENT_NAME, CITY
FROM DEPARTMENTS D LEFT JOIN EMPLOYEES E
ON D.DEPARTMENT_ID = E.DEPARTMENT_ID
LEFT JOIN LOCATIONS L ON D.LOCATION_ID = L.LOCATION_ID
GROUP BY DEPARTMENT_NAME, CITY;
RESULTADO: 27 rows.
Versión 1:
SELECT FIRST_NAME, LAST_NAME, SALARY
FROM EMPLOYEES
ORDER BY SALARY
FETCH FIRST 5 ROWS ONLY;
RESULTADO: 5 rows.
Versión 2:
SELECT * FROM (SELECT FIRST_NAME ,LAST_NAME,SALARY
FROM EMPLOYEES
ORDER BY SALARY)
WHERE ROWNUM < 6;
RESULTADO: 5 rows.
Versión 3:
SELECT * FROM (SELECT FIRST_NAME
FROM EMPLOYEES ORDER BY SALARY)
WHERE ROWNUM <=5
RESULTADO: 5 rows.
5. Generar texto de un archivo csv con los datos contenidos en la tabla employees,
usando como delimitador el '|', las columnas tipo varchar2 o char deben ir entre
comillas sencillas (')
Versión 1:
SELECT EMPLOYEE_ID ||'|'''|| FIRST_NAME ||'''|'''|| LAST_NAME ||'''|'''|| EMAIL
||'''|'''|| PHONE_NUMBER ||'''|'|| HIRE_DATE ||'|'''|| JOB_ID ||'''|'|| NVL(SALARY,'0')
||'|'||NVL(COMMISSION_PCT,'0') ||'|'|| NVL(MANAGER_ID,'0') ||'|'||
NVL(DEPARTMENT_ID,'0') AS "TEXTO PARA CSV"
FROM EMPLOYEES;
RESULTADO: Rows 1 - 50. More rows exist.
Versión 2:
SELECT EMPLOYEE_ID || '|' || CHR(39) || FIRST_NAME || CHR(39) || '|' || CHR(39) ||
LAST_NAME || CHR(39) || '|' || CHR(39) || EMAIL || CHR(39) || '|' || PHONE_NUMBER
|| '|' || HIRE_DATE|| '|' || JOB_ID || '|' ||SALARY|| '|' ||COMMISSION_PCT || '|' ||
MANAGER_ID || '|' ||DEPARTMENT_ID
FROM EMPLOYEES;
6. Generar texto para un archivo txt con los datos contenidos en la tabla employees
sin delimitador, pero cada columna de un tamaño fijo. Los números estén alineados
a la derecha y los textos a la izquierda, las fechas en formato DD/MM/YYYY
Versión 1:
SELECT CASE WHEN SALARY = (SELECT MIN(SALARY)
FROM EMPLOYEES) THEN
FIRST_NAME ||' ' || LAST_NAME || ' ' || ' * '
ELSE FIRST_NAME ||' ' || LAST_NAME|| ' ' || ' '
END RESULTADO
FROM EMPLOYEES;
Versión 2:
SELECT * FROM (SELECT EMPLOYEE_ID, FIRST_NAME, ' ' VALOR, SALARY
FROM EMPLOYEES
ORDER BY SALARY) UNION
SELECT * FROM (SELECT EMPLOYEE_ID, FIRST_NAME, '*' VALOR, SALARY
FROM EMPLOYEES
ORDER BY SALARY)
WHERE ROWNUM < 6 MINUS
SELECT * FROM (SELECT EMPLOYEE_ID, FIRST_NAME, ' ' VALOR, SALARY
FROM EMPLOYEES
ORDER BY SALARY)
WHERE ROWNUM < 6;
8. Usando como base las tablas employees (E) y departments (D) mostrar el resultado
de la unión, la intersección y la diferencia entre E y D e igualmente entre D y E.
Cada operación indicando número de registros mostrados y explicando cuando se
usaría cada operación
Versión 1:
UNION: Se usa cuando queremos ver los datos presentes en las dos tablas.
SELECT DEPARTMENT_ID AS CODDEPARTMENT FROM EMPLOYEES
UNION
SELECT DEPARTMENT_ID AS CODDEPARTMENT FROM DEPARTMENTS
RESULTADO: 28 rows
INTERSECT: Se usa cuando queremos ver los datos de la tabla 2 que están
presentes en la tabla 1.
SELECT DEPARTMENT_ID AS CODDEPARTMENT FROM EMPLOYEES
INTERSECT
SELECT DEPARTMENT_ID AS CODDEPARTMENT FROM DEPARTMENTS;
RESULTADO: 11 rows
MINUS D y E: Se una cuando queremos ver los datos de la tabla 2 que no están
presentes en la tabla 1.
SELECT DEPARTMENT_ID FROM DEPARTMENTS
MINUS
SELECT DEPARTMENT_ID FROM EMPLOYEES;
RESULTADO: 16 rows
MINUS E y D: Se una cuando queremos ver los datos de la tabla 2 que no están
presentes en la tabla 1.
SELECT DEPARTMENT_ID FROM EMPLOYEES
MINUS
SELECT DEPARTMENT_ID FROM DEPARTMENTS;
RESULTADO: 0 rows
Versión 2:
UNIÓN ENTRE E Y D
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E FULL OUTER JOIN DEPARTMENTS D ON
E.DEPARTMENT_ID=D.DEPARTMENT_ID;
UNIÓN ENTRE D Y E
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM DEPARTMENTS D FULL OUTER JOIN EMPLOYEES E ON
D.DEPARTMENT_ID=E.DEPARTMENT_ID;
INTERSECCIÓN ENTRE E Y D
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E INNER JOIN DEPARTMENTS D ON
E.DEPARTMENT_ID=D.DEPARTMENT_ID;
INTERSECCION ENTRE D Y E
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM DEPARTMENTS D INNER JOIN EMPLOYEES E ON
D.DEPARTMENT_ID=E.DEPARTMENT_ID;
DIFERENCIA ENTRE E Y D
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM EMPLOYEES E LEFT JOIN DEPARTMENTS D ON
E.DEPARTMENT_ID=D.DEPARTMENT_ID;
DIFERENCIA ENTRE D Y E
SELECT E.FIRST_NAME,E.LAST_NAME, D.DEPARTMENT_NAME
FROM DEPARTMENTS D LEFT JOIN EMPLOYEES E ON
D.DEPARTMENT_ID=E.DEPARTMENT_ID;
Versión 1:
SELECT FIRST_NAME, HIRE_DATE, FLOOR((SYSDATE-HIRE_DATE)/7) AS SEMANAS
FROM EMPLOYEES;
Versión 2:
SELECT EMPLOYEE_ID, FIRST_NAME, HIRE_DATE, TO_CHAR(((SYSDATE -
HIRE_DATE)/7), '999,999') SEMANAS
FROM EMPLOYEES;
Versión 3:
SELECT HIRE_DATE ,SYSDATE ,TO_DATE(SYSDATE, 'DD/MM/YYYY') -
TO_DATE(HIRE_DATE, 'DD/MM/YYYY') AS DIAS, (TO_DATE(SYSDATE, 'DD/MM/YYYY') -
TO_DATE(HIRE_DATE, 'DD/MM/YYYY'))/7 AS SEMANAS
FROM EMPLOYEES;
RESULTADO: Rows 1 - 50. More rows exist
10. Asumiendo que cada empleado ha laborado durante este mes cierto número de
días (usar para ello el día en que fue contratado, dado por la fecha HIRE_DATE),
calcular un incentivo para los que trabajaron más de 15 días de la siguiente manera
25-30 15
20-24 10
15-19 5
0-14 0
Versión 1:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, HIRE_DATE,
TO_CHAR(HIRE_DATE,'DD'), SALARY, AUMENTO, (SALARY + AUMENTO) NUE_SAL
FROM (SELECT EMP.*,
CASE
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 25 AND 30 THEN salary * 0.15
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 20 AND 24 THEN salary * 0.10
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 15 AND 19 THEN salary * 0.05
ELSE 0 END AUMENTO
FROM EMPLOYEES EMP);
Versión 2:
SELECT E.EMPLOYEE_ID, E.FIRST_NAME || ' '|| E.LAST_NAME NOMBRE_EMPLEADO,
E.HIRE_DATE, CASE
WHEN TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD') <= 14 THEN 0
WHEN TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD')> 14 AND
TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD') <= 19 THEN 5
WHEN TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD') > 19 AND
TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD') <= 24 THEN 10
ELSE
15
END "INCENTIVO %"
FROM EMPLOYEES E
WHERE TO_CHAR(TO_DATE(E.HIRE_DATE), 'DD') > 14;
Versión 4:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, HIRE_DATE,
TO_CHAR(HIRE_DATE,'DD'), SALARY, AUMENTO, (SALARY + AUMENTO) NUE_SAL
FROM (SELECT EMP.*, CASE
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 25 AND 30 THEN SALARY * 0.15
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 20 AND 24 THEN SALARY * 0.10
WHEN TO_CHAR(HIRE_DATE,'DD') BETWEEN 15 AND 19 THEN SALARY * 0.05
ELSE 0 END AUMENTO
FROM EMPLOYEES EMP);
11. Generar un listado de los empleados acreedores de un incentivo del 5% del salario,
acorde a la primera letra del nombre, verificando si el valor del mes y el carácter
ASCII de la primera letra del nombre son par o impar. Ejemplo: Abril es el mes 4
(par) y si el ASCII de la primera letra del nombre es par, se hace acreedor al
incentivo. Nota: La función ASCII('caracter') devuelve el valor ASCII asignado a
'caracter'.
Versión 1:
SELECT EMPLOYEE_ID, FIRST_NAME, SUBSTR(FIRST_NAME, 0, 1) AS "LETRA",
ASCII(SUBSTR(FIRST_NAME, 0, 1)) AS "ASCII_LETRE",
TO_CHAR(TO_DATE(HIRE_DATE), 'MM') AS "MES"
FROM EMPLOYEES
WHERE MOD(TO_CHAR(TO_DATE(HIRE_DATE), 'MM'), 2) = 0
AND MOD(ASCII(SUBSTR(FIRST_NAME, 0, 1)),2) = 0;
RESULTADO: 28 rows
Versión 2:
SELECT EMPLOYEE_ID,FIRST_NAME, SALARY+(SALARY*0.05) AS
SALARIO_DE_INCENTIVO
FROM EMPLOYEES
WHERE (MOD( TO_CHAR(HIRE_DATE, 'MM') , 2 ) = 0 AND MOD(ASCII(FIRST_NAME),
2)=0)
ORDER BY 1;
RESULTADO: 28 rows
12. Generar un listado con el nivel del empleado acorde al salario devengado usando
para ello los siguientes intervalos
Intervalo Nivel
1-5000 1
5001-10000 2
10001-50000 3
50001-100000 4
Versión 1:
CREATE TABLE INTERVALS(LEVEL_INTERVAL NUMBER(1), MIN NUMBER(8,2), MAX
NUMBER(8,2));
Versión 2:
SELECT EMPLOYEE_ID, FIRST_NAME, LAST_NAME, SALARY, NIVEL
FROM (SELECT EMP.*, CASE
WHEN SALARY BETWEEN 1 AND 5000 THEN 1
WHEN SALARY BETWEEN 5001 AND 10000 THEN 2
WHEN SALARY BETWEEN 10001 AND 50000 THEN 3
WHEN SALARY BETWEEN 50001 AND 100000 THEN 4 END NIVEL
FROM EMPLOYEES EMP);
13. Con el ánimo de generar políticas de bienestar se nos pide un listado del número de
empleados por nivel salarial; categoría o nivel dado por la siguiente clasificación
salarial
Intervalo Nivel
1-5000 1
5001-10000 2
10001-50000 3
50001-100000 4
Versión 1:
CREATE TABLE INTERVALS(LEVEL_INTERVAL NUMBER(1), MIN NUMBER(8,2),
MAX NUMBER(8,2));
RESULTADO: 4 rows
Versión 2:
CREACIÓN DE TABLA:
CREATE TABLE EMPLOYEE_GRADE (EMPLOYEE_LEVEL VARCHAR2(3), MIN_SALARY
NUMBER, MAX_SALARY NUMBER)
CONSULTA:
SELECT J.EMPLOYEE_LEVEL NIVEL,(SELECT COUNT (1)
FROM EMPLOYEES E
WHERE E.SALARY BETWEEN J.MIN_SALARY
AND J.MAX_SALARY) AS
NUMERO_DE_EMPLEADOS
FROM EMPLOYEE_GRADE J;
RESULTADO: 4 rows
14. Se nos pide un listado de la proyección del costo de la nómina actual de acuerdo a
la convención sindical recientemente firmada que dice que para el 1er año el
aumento sería del 10%, para el 2do año 5% y para el 3er año el 4%
Algo así
Proyección Costo
========== =========
1er año #########
2do año ########
3er año #########
CREACIÓN DE VISTAS:
CREATE VIEW Costo AS SELECT SUM(salary)+SUM(salary)*0.1 SALARIO
FROM EMPLOYEES
CONSULTA:
SELECT '==================' Proyeccion, '==================' Costo
FROM DUAL;
UNION
SELECT '1er año'Proyeccion , (SELECT TO_CHAR (salario)FROM Costo) Costo
FROM DUAL;
UNION
SELECT '2do año'Proyeccion, (SELECT TO_CHAR (salario)FROM Costo1) Costo
FROM DUAL;
UNION
SELECT '3er año'Proyeccion, (SELECT TO_CHAR (salario)FROM Costo11) Costo
FROM DUAL
ORDER BY 1;
REGISTROS: 4 rows
15. Generar el texto de un mensaje vía email felicitando a los empleados por su labor
durante el año inmediatamente anterior con las siguientes condiciones
sí salario está en el intervalo 0-5000 10%, para el intervalo 5001-10000, el 7% y
para el resto de empleados, el 2%. El texto debe tener la siguiente estructura
Destinatario: email de la forma primera letra del
nombre+apellido+'@empresa.com.co'
Asunto: Beneficio para el 2021
Texto: Estimado señor(a) nombre+' '+ apellido con base en el desempeño mostrado
durante el 2020 se autoriza un aumento a su salario del (aquí va el % según criterio
mostrado arriba) lo que significa que su salario para el 2021 será de $(valor
calculado)
Cordialmente, el jefe
Nota: Para introducir en un texto un salto de línea, se puede hacer concatenando al
texto el CHR(10), para introducir una comilla sencilla se usa el CHR(39)
Ejemplo: Pedro Pérez, salario 4500
Resultado sería
Destinatario: [email protected]
Asunto: Beneficio para el 2021
Texto: Estimado señor(a) Pedro Pérez con base en el desempeño mostrado durante
el 2020 se autoriza un aumento a su salario del 10% lo que significa que su salario
para el 2021 será de $4950.
Cordialmente, el Jefe
SELECT
CASE
WHEN SALARY BETWEEN 0 AND 5000 THEN 'DESTINATARIO: ' ||
LOWER(CONCAT(SUBSTR(FIRST_NAME,1,0),
CONCAT(EMAIL,'@EMPRESA.COM.CO')))||CHR(10) ||'ASUNTO: BENEFICIO
PARA EL 2021'||CHR(10) ||
'ESTIMADO SEÑOR(A): '||FIRST_NAME||' '||
LAST_NAME||' CON BASE EN EL DESEMPEÑO MOSTRADO DURANTE EL 2020
SE AUTORIZA UN AUMENTO A SU SALARIO DEL'
||' 10% ' ||'LO QUE SIGNIFICA QUE SU SALARIO PARA
EL 2021 SERÁ DE: $'||TO_CHAR(SALARY+(SALARY*0.1) ) ||CHR(10) ||
'CORDIALMENTE, EL JEFE'
WHEN SALARY BETWEEN 5001 AND 10000 THEN 'DESTINATARIO: ' ||
LOWER(CONCAT(SUBSTR(FIRST_NAME,1,0),
CONCAT(EMAIL,'@EMPRESA.COM.CO')))||CHR(10) ||'ASUNTO: BENEFICIO
PARA EL 2021'||CHR(10) ||
'ESTIMADO SEÑOR(A): '||FIRST_NAME||' '||
LAST_NAME||' CON BASE EN EL DESEMPEÑO MOSTRADO DURANTE EL 2020
SE AUTORIZA UN AUMENTO A SU SALARIO DEL'
||' 7% ' ||'LO QUE SIGNIFICA QUE SU SALARIO PARA
EL 2021 SERÁ DE: $'||TO_CHAR(SALARY+(SALARY*0.07) ) ||CHR(10) ||
'CORDIALMENTE, EL JEFE'
NOTA DE LA ACTIVIDAD:
La verificación de las consultas se realizaron en las herramientas Oracle APEX y
Oracle Live.