UTNianos

Versión completa: [APORTE] Final Gestión de Datos 25/02/2014
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Les dejo el Final de GDD del 25/02/14.

Saludos.
Que grande!! Tenes la resolución?
Recién lo hice, a mi me dio:

3)a) La respuesta es la B. El Join entre empresa y área hace una fila sea “empresas con al menos un 1 area” por lo que se puede descartar la opción A. El Left Join entre áreas y empleados que traiga todas las áreas con sus empleados (si los tiene), por lo que NO se cumple “al menos 1 área y 1 empleado”. Se descarta entonces la opción C. Los registros se agrupan por empresa por lo que el count distinct hace que se cuenten la cantidad de áreas distintas que tiene una empresa (el distinct es porque por el join entre área y empleados puede haber muchos registro para una misma área). Y el último count cuenta la cantidad de empleados de la empresa.

3)b) Este no estoy seguro, no lo chequee

Select e.id_empresa, count(distinct a.id_area), count (em.id_empresa)
from empresa e
join area a on e.id_empresa = a.id_empresa
left join empleado em on (a.id_area=em.id_area and aid_empresa=em.id_empresa)
where not exist (Select e2.id_empresa, a2.id_area
from empresa e2
join area a2 on e2.id_empresa = a2.id_empresa
left join empleado em2 on (a2.id_area=em2.id_area and a2.id_empresa=em2.id_empresa)
where e.id_empresa = e2.id_empresa
group by e2.id_empresa, a2.id_area
having count (a2.id_area) > 10)

group by e.id_empresa
Estuve probando el codigo y efectivamente como dijo el compañero, la respuesta es la B en el primer punto practico. Saludos!
Aporto el 3.B, una solución que probé y por lo que veo funcionó Ok. Lo que hice fue editar cuando hace el Join con la tabla Area, para que esa tabla contenga las areas con mas de 10 empleados:


select e.id_empresa, COUNT(distinct a.id_area) areas, COUNT(em.cuit) empleados from
empresa e join (select a.id_empresa, a.id_area , COUNT(em.cuit) empleados from Area a, empleado em where
em.id_area= a.id_area and em.id_empresa= a.id_empresa group by a.id_empresa,a.id_area having COUNT(em.cuit) <= 10)
a on e.id_empresa = a.id_empresa join empleado em on
(a.id_area=em.id_area and a.id_empresa=em.id_empresa)
group by e.id_empresa

Hola, añado mis respuestas sobre la teoria:

1A) Verdadero
[attachment=10479]
1B) Falso
Un contraejemplo seria, 2 nodos que se apuntan entre si, cada nodo tiene grado 2, el grafo tiene grado 2 pero no se puede representar como un arbol binario
Creo que esta es una forma posible de hacer el 3b) :

select E.id_empresa ,count(distinct A.id_area) cantidad_de_areas,count(*) cantidad_de_empleados

from empresa E join area A on (E.id_empresa=A.id_empresa)
join empleado Em on (A.id_area=Em.id_area and A.id_empresa=Em.id_empresa)

group by E.id_empresa

having (select top 1 count(*) cantidad from area A1 join empleado Em1
on (A1.id_area=Em1.id_area and A1.id_empresa=Em1.id_empresa)
where A1.id_empresa=E.id_empresa group by A1.id_area order by cantidad desc)<=10

Nota:: No tome en cuenta eso de que muestre las empresas que tienen almenos 1 area, ya que cuando se hace el join, si no machea con ningun area se descarta automáticamente la empresa.
(20-02-2015 17:48)aleixen escribió: [ -> ]Creo que esta es una forma posible de hacer el 3b) :

select E.id_empresa ,count(distinct A.id_area) cantidad_de_areas,count(*) cantidad_de_empleados

from empresa E join area A on (E.id_empresa=A.id_empresa)
join empleado Em on (A.id_area=Em.id_area and A.id_empresa=Em.id_empresa)

group by E.id_empresa

having (select top 1 count(*) cantidad from area A1 join empleado Em1
on (A1.id_area=Em1.id_area and A1.id_empresa=Em1.id_empresa)
where A1.id_empresa=E.id_empresa group by A1.id_area order by cantidad desc)<=10

Nota:: No tome en cuenta eso de que muestre las empresas que tienen almenos 1 area, ya que cuando se hace el join, si no machea con ningun area se descarta automáticamente la empresa.

No entiendo porque hiciste el subselect en el having. Yo lo plantee igual pero en vez del subselect directamente puse:

HAVING COUNT(*) <= 10

ya que el count te devuelve la cantidad de empleados por área de cada empresa


saludos


aah, queria aclarar que en el group by yo agrupe por empresa y por area, no se si esta bien como lo plantee
(24-02-2015 13:46)Nacho14 escribió: [ -> ]
(20-02-2015 17:48)aleixen escribió: [ -> ]Creo que esta es una forma posible de hacer el 3b) :

select E.id_empresa ,count(distinct A.id_area) cantidad_de_areas,count(*) cantidad_de_empleados

from empresa E join area A on (E.id_empresa=A.id_empresa)
join empleado Em on (A.id_area=Em.id_area and A.id_empresa=Em.id_empresa)

group by E.id_empresa

having (select top 1 count(*) cantidad from area A1 join empleado Em1
on (A1.id_area=Em1.id_area and A1.id_empresa=Em1.id_empresa)
where A1.id_empresa=E.id_empresa group by A1.id_area order by cantidad desc)<=10

Nota:: No tome en cuenta eso de que muestre las empresas que tienen almenos 1 area, ya que cuando se hace el join, si no machea con ningun area se descarta automáticamente la empresa.

No entiendo porque hiciste el subselect en el having. Yo lo plantee igual pero en vez del subselect directamente puse:

HAVING COUNT(*) <= 10

ya que el count te devuelve la cantidad de empleados por área de cada empresa


saludos


aah, queria aclarar que en el group by yo agrupe por empresa y por area, no se si esta bien como lo plantee


ojo porque si agrupas por empresa -area tenes estos problemas
- tenes que cambiar el count de empleados (ahora no vas a ver el de la empresa completa, sino el de la combinación empresa-area)
- el having te filtraría areas que tengas menos de 10 pero que pasa si tenes 2 áreas con mas de 10 empleados ? El having no las filtraría y como estas agrupando por empresa - area verias 2 filas (y tenes que devolver una fila por empresa)

para mi como lo hizo aleixen está bien
(24-02-2015 13:58)gonnza escribió: [ -> ]
(24-02-2015 13:46)Nacho14 escribió: [ -> ]
(20-02-2015 17:48)aleixen escribió: [ -> ]Creo que esta es una forma posible de hacer el 3b) :

select E.id_empresa ,count(distinct A.id_area) cantidad_de_areas,count(*) cantidad_de_empleados

from empresa E join area A on (E.id_empresa=A.id_empresa)
join empleado Em on (A.id_area=Em.id_area and A.id_empresa=Em.id_empresa)

group by E.id_empresa

having (select top 1 count(*) cantidad from area A1 join empleado Em1
on (A1.id_area=Em1.id_area and A1.id_empresa=Em1.id_empresa)
where A1.id_empresa=E.id_empresa group by A1.id_area order by cantidad desc)<=10

Nota:: No tome en cuenta eso de que muestre las empresas que tienen almenos 1 area, ya que cuando se hace el join, si no machea con ningun area se descarta automáticamente la empresa.

No entiendo porque hiciste el subselect en el having. Yo lo plantee igual pero en vez del subselect directamente puse:

HAVING COUNT(*) <= 10

ya que el count te devuelve la cantidad de empleados por área de cada empresa


saludos


aah, queria aclarar que en el group by yo agrupe por empresa y por area, no se si esta bien como lo plantee


ojo porque si agrupas por empresa -area tenes estos problemas
- tenes que cambiar el count de empleados (ahora no vas a ver el de la empresa completa, sino el de la combinación empresa-area)
- el having te filtraría areas que tengas menos de 10 pero que pasa si tenes 2 áreas con mas de 10 empleados ? El having no las filtraría y como estas agrupando por empresa - area verias 2 filas (y tenes que devolver una fila por empresa)

para mi como lo hizo aleixen está bien

ok
1a V. El heapsort es el mejor ejemplo.
1b F. Cualquier grafo de grado 2 con un ciclo sirve de contraejemplo.

2b Supongo que es explicar un poco el modelo ANSI/SPARC, nivel externo, nivel conceptual y nivel interno (apunte Zaffaroni Base de Datos v3).

3a La opción b, como explicaron arriba.
3b Propongo otra solución que me pareció más simple. Reutilicé la query del 3a y le agregué un where nomás:


where not exists(
select id_area
from empleado emp
where e.id_empresa = emp.id_empresa
group by id_area
having COUNT(cuit) > 10
)


Básicamente, la subquery traería (si no pifié) todas las áreas de la empresa que tienen más de 10 empleados. Si no hay ninguna entonces la empresa cumple con no tener ningún área con más de 10 empleados. El resto queda igual porque pide exactamente lo mismo. Y como la pk de la tabla empleado tiene el id del área y de la empresa, no hace falta ningún join.

No lo probé, pero creo que anda. La query completa quedaría así:


select e.id_empresa, COUNT(distinct a.id_area), COUNT(em.cuit)
from empresa e join area a on e.id_empresa = a.id_empresa
left join empleado em on (em.id_empresa = a.id_empresa and em.id_area = a.id_area)

where not exists(
select id_area
from empleado emp
where e.id_empresa = emp.id_empresa
group by id_area
having COUNT(cuit) > 10
)

group by e.id_empresa

no sera que para el 3b

Select e.id_empresa, count(distinct a.id_area), count (em.id_empresa)
from empresa e
join area a on e.id_empresa = a.id_empresa
left join empleado em on (a.id_area=em.id_area and aid_empresa=em.id_empresa)
group by e.id_empresa
having count (em.id_empresa) <=10

?????
URLs de referencia