Ver Mensaje Individual
  #8 (permalink)  
Antiguo 26/11/2014, 19:31
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: .:Realizar consulta devolviendo valores NULL:.

A ve si se entiende cómo lo veo:
- Tienes N alumnos que pertenecen a la institución.
- Cada alumno debe responder a N exámenes o Ejercicios, y el mismo Ejercicio debe ser respondido por N Alumnos.
- Cada Ejercicio consiste en N consignas o Premisas a solucionar. Cada Premisa es respondida en N ejercicios, correspondiente a cada alumno.
- Cada premisa solucionada por cada alumno en cada examen se registra de forma unívoca, pero si no se ha solucionado no se registra.

En ese contexto, hay.
1. Relación N:N entre Alumnos y Ejercicios.
2. Relación N:N entre Ejercicio y Premisa.
3) Relación N:N.N entre Alumno, Ejercicio y Premisa.

DE acuerdo a este esquema se determina que existen las siguientes entidades:
1) Alumno(alumno_id, apellido, nombre, documento, ...)
2) Ejercicio(ejercicio_id, descripcion, ...)
3) Alumno_Ejercicio(alumno_id, ejercicio_id, fecha_ejercicio, ...)
4) Premisa(premisa_id, descripcion, ...)
5) Ejercicio_premisa(ejercicio_id, premisa_id, ...)
6) Premisa_solucion(alumno_id, ejercicio_id, premisa_id[, ...])

Para averiguar qué alumno no respondió una premisa hay que hacer una consulta bastante compleja...

Primero cruzar los alumnos con los exámenes:
Código MySQL:
Ver original
  1. SELECT ...
  2. FROM alumno A INNER JOIN alumno_ejercicio AE on A.alumno_id = ae.alumno_id
  3.    INNER JOIN ejercicio E ON AE.ejercicio_id = E.ejercicio_id;
Eso devolverá los ejercicios en los que participó.
Luego hay que cruzar eso con las premisas, que están el la quinta tabla, y si quieres los detalles con la cuarta, la de las premisas:
Código MySQL:
Ver original
  1. SELECT ...
  2. FROM alumno A INNER JOIN alumno_ejercicio AE on A.alumno_id = ae.alumno_id
  3.    INNER JOIN ejercicio E ON AE.ejercicio_id = E.ejercicio_id;
  4.    INNER JOIN ejercicio_premisa EP ON E.ejercicio_id = EP.ejercicio_id
  5.    INNER JOIN premisa P ON EP.premisa_id = P.premisa_id
Esto devuelve el listado completo de lo que compone el ejercicio, con todas sus premisas.
Recién en ese punto se puede resolver lo que quieres, pero esa relacion es múltiple por lo que el ON es más complejo:
Código MySQL:
Ver original
  1. SELECT ...
  2. FROM alumno A INNER JOIN alumno_ejercicio AE on A.alumno_id = ae.alumno_id
  3.    INNER JOIN ejercicio E ON AE.ejercicio_id = E.ejercicio_id;
  4.    INNER JOIN ejercicio_premisa EP ON E.ejercicio_id = EP.ejercicio_id
  5.    INNER JOIN premisa P ON EP.premisa_id = P.premisa_id
  6.    LEFT JOIN premisa_solucion PS ON P.premisa_id = PS.premisa_id AND A.alumno_id = PS.alumno_id AND E.ejercicio_id = PS.ejercicio_id
  7. WHERE [condiciones] AND (... OR PS.alumno_id IS NULL)

¿Se va entendiendo?

Se puede excluir la tabla de ejercicio_premisa si y sólo si una premisa sólo puede pertenecer a un único ejercicio. Eso es algo que dependerá de la definición del caso.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)