viernes, 15 de abril de 2011

Solucion del Examen

Esta es la solucion al examen

Ejercicio 1 Bases de Datos: muestre los apellidos y nombres ordenados alfabeticamente, de todos los gerentes en los que haya estado un empleado laborando en algun puesto MENOS DE TRES MESES, asuma mes comercial de 30 dias, use la base HR de oracle
Solucion 1: SELECT last_name, first_name
FROM hr.employees e
WHERE EMPLOYEE_ID IN (select d.manager_id from hr.departments d where manager_id is not null )
AND employee_id in (select manager_id from hr.employees where months_between(sysdate,hire_date) < 3.0)
ORDER BY last_name, first_name;
esta es la mas facil, selecciono nombres y apellidos, y filtro el employee_id para que sea igual una subconsulta donde obtengo todos los managers de empleados, y claro ademas filtro otra vez el employee_id para los empleados de menos de 3 meses
 
 SELECT last_name,first_name
FROM hr.employees
WHERE employee_id in (select manager_id from hr.employees where (sysdate-hire_date < 90) )
ORDER BY last_name, first_name;
Todavia mas facil, filtro el employee_id eligiendo los manager_id de los empleados que tienen menos de 90 dias, recordemos que al restar dos fechas obtenemos el numero de dias entre las dos fechas
 
Ejercicio 2: Realice una consulta que muestre el nombre de la region y pais, citando para cada uno de los paises, muestre el total de empleados que laboran en cada pais, y ademas el coeficiente de rotacion de personal (total empleados entre total de empleados despedidos o que cambiaron hacia otro puesto) esquema HR oracle
SELECT r.region_name, p.country_id, p.country_name , count(e.employee_id) as total_empleados
,
count(e.employee_id) / (
select count(j.employee_id) from HR.job_history j natural join hr.departments natural join hr.locations x where x.country_id = p.country_id 
) as COF
FROM hr.regions r join hr.countries p on (r.region_id=p.region_id) join hr.locations l on
(l.country_id=p.country_id) natural join hr.departments natural join hr.employees e
GROUP BY r.region_name, p.country_id, p.country_name
Esta esta mas divertida, primero se hace la cascada de relaciones, desde regions, hasta employees, colocando alias a las tablas, se inicia normalmente, hasta el count, luego si te fijas, utilizo el campo de la consulta externa p.country para filtar la consulta interna, para sacar el coeficiente que pide, pues estamos agrupando por el country_id.
 
Ejercicio 3: Realice una consulta que muestre el Department_id, el Department_name, el total de empleados por departamento, la cantidad de dias promerio que tienen laborando los empleados en dicho depto, y el nombre y el apellido del empleado que tiene mas dias laborando en ese depto (asuma que solo hay un empleado con mas dias laborando), muestre solo la informacion para deptos que tienen mas de 3 empleados laborando
SELECT d.department_id,d.department_name, count(e.employee_id) as Total_Empleados
, avg(sysdate-e.hire_date) as DiasProm
 , (select max( x.first_name) from hr.employees x where x.department_id=d.department_id
 AND (sysdate-x.hire_date) = ( select max(sysdate-e2.hire_date) from hr.employees e2 where e2.DEPARTMENT_ID=d.department_id )
  ) as Nombre,
(select max( x.last_name) from hr.employees x where x.department_id=d.department_id
 AND (sysdate-x.hire_date) = ( select max(sysdate-e2.hire_date) from hr.employees e2 where e2.DEPARTMENT_ID=d.department_id )
 )  as Apellidos
FROM hr.departments d join hr.employees e on (d.department_id=e.department_id)
GROUP BY d.department_id, d.department_name ;
  me gustaria que ustedes comenten esta consulta...




.

2 comentarios:

Unknown dijo...

estan bien fumadas las consultas jejeje

Brayan Ruben Copa Siles dijo...

Las dos soluciones del primer enunciado estan mal ya que si bien se refiere a que hay que mostrar a los gerentes que han tenido subordinados trabajando NO en la empresa SINO en algun puesto ; ahora bien debemos verificar las estancias en los puestos en la tabla de job_history luego en mi solucion en la primera parte del UNION se hace eso en la segunda parte verficamos si puesto actual pero tomando como primer dia de trabajo el maximo end_date si no existe entonces recien tomamos hire_date como valor usamos UNION en vez UNION ALL para evitar duplicados en el caso de que tenga mas dde un puesto con estancia menor a 3 meses SELECT last_name,first_name
FROM employees
WHERE employee_id IN
( SELECT manager_id FROM employees e,job_history jh
WHERE e.job_id = jh.job_id
AND end_date < ADD_MONTHS(start_date,3)
UNION
SELECT manager_id FROM employees e
WHERE sysdate < ADD_MONTHS(
NVL((SELECT MAX(end_date) FROM job_history jh
WHERE e.employee_id = jh.employee_id),hire_date
),3)
)ORDER BY last_name,first_name