Conlsulta SQL Left Join Y Subconsultas

Llevo unos días intentando realizar una consulta en mi base de datos que no logro conseguir finalizar.
Voy a intentar explicarlo de la mejor manera posible.

Tengo una base de datos con empleados. Estos empleados tienen cursos. Hay unos cursos que corresponden en la plantilla, un curso puede corresponder a varios tipos y varios empleados.

Hay diferentes tipos de empleados administrativos, ejecutivos, oficiales y técnicos, divididos en secciones u oficinas.

Para todo ello tengo las siguientes tablas.

[EMPLEADOS]
DNI
Nombre
Apellido
2 apellido
Teléfono
Dirección
FOTO
...

[EMPRESA]
DNI 
FECHA_INICIO 
TIPO 
TELEFONO_EMPRESA 
SECCION 
DNI_RESPONSABLE
...

[TIPO]
ID_TIPO
NOMBRE 
...

[CURSOS_CORRESPONDIENTES]
ID_CURSO 
Nombre
Ejecutivo
Adminitrativo
Oficiales
TÉCNICOS
...

[CURSOS_EMPRESA]
DNI
ID_CURSO
FECHA_INICIO
FECHA_FIN

Mi intención en realizar una consulta con los cursos correspondientes, y los empleados, en numero, que en la empresa hay.

EJEMPLO

                                      ADMINISTRATIVOS            EJECUTIVOS           OFICIALES          TÉCNICOS
                                       Corres.        Poseen     corresp.   Poseen.    corresp. Poseen. Corresp. Poseen.

SEGURIDAD LABORAL    0                  1                 2               2              5            3            10         15
... .. .. .. .. .. .. .. ..

He conseguido una consulta con left join de los cursos correspondientes, contando cuantos empleados tienen un curso.
Pero no he podido dividirlos en sus respectivos tipos, ni probando con un solo tipo de empleado.

Respuesta
1

Me confunde tu modelo de base de datos. Es más fácil entender si se conoce cómo se relacionan las tablas, es decir, los campos primary key y foreign key y qué campo se relaciona con qué campo. Sumado a un buen diseño, no debe existir problemas para realizar el left join (o cualquiera outer join). En primer lugar te diré lo que me confunde y luego te comento sobre las left join.

[CURSOS_CORRESPONDIENTES] parece tener campos llamados: Ejecutivo, técnicos, oficiales, etc. Si son campos, ¿Cuál es el contenido? Una especie de: sí, no. Me parece aquí hay un fallo de diseño si es así, esas palabras tienen más que ver con contenido de un campo y no el nombre de un atributo o columna.

[EMPRESA] da a entender que gestionas una BBDD para varias empresas. O talvez, con ello te refieres a Oficinas. Además, no veo cómo es la relación con [EMPLEADOS] pues veo un campo "Seccion" en [EMPRESA] y no en [EMPLEADOS] (Que saldría de una relación 1:N en el modelo conceptual, de ser el caso)

[TIPO] es tipo de curso si se relaciona con [CURSOS_EMPRESA], aquí el campo: Nombre, ¿ya nos dice lo de Técnico, administrativo, etc? Que antes dije no entender por qué están como campos en [CURSOS_CORRESPONDIENTES]. Al final, me dices que no los puedes sacar según tipo de empleado. ¿Pero dónde está el tipo de empleado? ¿Es un campo de [EMPLEADOS] que es foreign key con...¿? Si no, no vamos a sacar nunca la LEFT JOIN por tipo de empleado; por tipo de curso sí, ya que se relaciona con [CURSOS] (parece ser que debe existir porque también dudo de [CURSOS_EMPRESA] ya que no le veo el sentido de un campo dni en una tabla de Cursos, sí en la tabla resultante de la relación entre Cursos y Empleados, que entiendo es [CURSOS_EMPRESA]).

Hay que tener en cuenta que si se realiza, por ejemplo, una LEFT JOIN es para sacar todas las filas del lado izquierdo aunque no estén relacionadas. Si tenemos las supuestas tablas con sus datos (no campos):

[EMPRESA]
E1
E2
E3

[EMPLEADOS]
EMP1
EMP2
EMP3
EMP4
EMP5

[CURSO_EMPRESA]
EMP1 C1
EMP1 C2
EMP2 C1
EMP2 C3
EMP5 C3
[CURSO]
C1
C2
C3

[CURSO_CORRESPONDIENTE]
C1 T1
C2 T2
C2 T1
[TIPO]
T1
T2
Al querer listar todos los empleados con sus datos relacionados, se referencia a dicha tabla según el orden que utilizamos para ir uniendo las tablas y, es un orden que se ve fácilmente con el modelo conceptual:
SELECT idempresa, empleados.dni, cursos.idcurso, tipo.idtipo
FROM Empresa RIGHT JOIN Empleados ON (empresa.idempresa = empleados.idempresa)
LEFT JOIN Curso_Empresa ON (empleados.dni = curso_empresa.dni)
LEFT JOIN Cursos ON (curso_empresa.idcurso = cursos.idcurso)
LEFT JOIN Cursos_correspondiente ON (cursos.idcurso = cursos_correspondientes.idcurso)
LEFT JOIN Tipo ON (cursos_correspondientes.idtipo = tipo.idtipo);
El resultado sería:
E1 EMP1 C1 T1
E1 EMP1 C1 T2
E1 EMP1 C2 T1
E1 EMP2 C1 T1
E1 EMP2 C1 T2
E1 EMP2 C3
E1 EMP3
E1 EMP4
E2 EMP5 C3
Como el C1 es de dos tipos diferentes tenemos la fila 1 y 2. Lo mismo pasa con la 4 y 5. El tipo es de curso, no tipo de empleado. Si queremos contar, debemos tener cuidado de qué ponemos en el COUNT y en el GROUP BY, ya que si simplemente ponemos COUNT(dni) y GROUP BY(idtipo) tendríamos:
3 T1
2 T2
4 (ahora mismo dudo si los nulos los contaría como un solo grupo)
Mientras que si se pone COUNT(DISTINCT dni) y GROUP BY(idtipo) tendríamos:
2 T1
2 T2
4
En resumen, asegurarte de que el modelo está bien diseñado y ten claro los campos que sirven para relacionar las tablas. En base a esos campos se realiza la cláusula ON de la JOIN. Y lo de LEFT, RIGHT o FULL ya es según de qué lado se quiere todas las filas, según lo escribes en la sentencia. Cuyo orden es según se relaciona la una con la otra.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas