Ver Mensaje Individual
  #6 (permalink)  
Antiguo 01/12/2014, 10:13
Avatar de NSD
NSD
Colaborador
 
Fecha de Ingreso: mayo-2012
Ubicación: Somewhere
Mensajes: 1.332
Antigüedad: 11 años, 11 meses
Puntos: 320
Respuesta: POSICION de un elemento dentro de un conjunto de datos

Ehhhh......

A ver, vamos por partes.

1) En el editor, arriba, hay una opcion que dice Highlight, se usa para poner codigo, por favor, cuando publiques codigo de culquier lenguaje, usa esa opcion.

2) ¿Tablas con 44 columnas? y si mañana se agrega una materia mas, ¿Agregas otra columna a la tabla? eso esta mal. En si esta mal el modelo de datos, por lo tanto todo lo que venga después de eso también estará mal ya que acarrea un error de mal diseño.

Lo que tienes que hacer como punto de partida, es rearmar la base de datos.

La idea es que separes cada cosa en una tabla diferente.

Las materias:
Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `materias` (
  2.   `nombre` char(100) NOT NULL,
  3.   PRIMARY KEY (`codigo`)
  4.  
  5. --
  6. -- Volcado de datos para la tabla `materias`
  7. --
  8.  
  9. INSERT INTO `materias` (`codigo`, `nombre`) VALUES
  10. (1, 'Castellano'),
  11. (2, 'Ingles'),
  12. (3, 'Matematica'),
  13. (4, 'Informatica');

Los cursos:

Código MySQL:
Ver original
  1. CREATE TABLE IF NOT EXISTS `cursos` (
  2.   `nombre` char(100) NOT NULL,
  3.   PRIMARY KEY (`codigo`)
  4.  
  5. --
  6. -- Volcado de datos para la tabla `cursos`
  7. --
  8.  
  9. INSERT INTO `cursos` (`codigo`, `nombre`) VALUES
  10. (1, '1a'),
  11. (2, '1b'),
  12. (3, '2a'),
  13. (4, '2b');

Los alumnos pertenecen solo a un curso, por lo que hay que relacionarlos:
Código MySQL:
Ver original
  1. --
  2. -- Estructura de tabla para la tabla `alumnos`
  3. --
  4.  
  5. CREATE TABLE IF NOT EXISTS `alumnos` (
  6.   `nombre` char(100) NOT NULL,
  7.   `curso` int(10) unsigned DEFAULT NULL,
  8.   PRIMARY KEY (`cedula`),
  9.   KEY `curso` (`curso`)
  10.  
  11. --
  12. -- Volcado de datos para la tabla `alumnos`
  13. --
  14.  
  15. INSERT INTO `alumnos` (`cedula`, `nombre`, `curso`) VALUES
  16. (1, 'French', 1),
  17. (2, 'Beruti', 1),
  18. (3, 'Vicente Lopez', 1),
  19. (4, 'Mitre', 3),
  20. (5, 'Belgrano', 3),
  21. (6, 'San Martin', 3);
  22.  
  23. --
  24. -- Restricciones para tablas volcadas
  25. --
  26.  
  27. --
  28. -- Filtros para la tabla `alumnos`
  29. --
  30. ALTER TABLE `alumnos`
  31.   ADD CONSTRAINT `alumnos_ibfk_1` FOREIGN KEY (`curso`) REFERENCES `cursos` (`codigo`) ON DELETE SET NULL ON UPDATE CASCADE;

Las materias pertenecen a 1 o mas cursos, por ejemplo, todos los 1º tendrán las mismas materias (quizá con otros profesores, pero eso es otro tema aparte), por lo que hay que relacionar las materias con los cursos:

Código MySQL:
Ver original
  1. --
  2. -- Estructura de tabla para la tabla `materiasxcurso`
  3. --
  4.  
  5. CREATE TABLE IF NOT EXISTS `materiasxcurso` (
  6.   `curso` int(10) unsigned NOT NULL,
  7.   `materia` int(10) unsigned NOT NULL,
  8.   PRIMARY KEY (`curso`,`materia`),
  9.   KEY `materia` (`materia`)
  10.  
  11. --
  12. -- Volcado de datos para la tabla `materiasxcurso`
  13. --
  14.  
  15. INSERT INTO `materiasxcurso` (`curso`, `materia`) VALUES
  16. (1, 1),
  17. (2, 1),
  18. (1, 2),
  19. (2, 2),
  20. (3, 3),
  21. (4, 3),
  22. (3, 4),
  23. (4, 4);
  24.  
  25. --
  26. -- Restricciones para tablas volcadas
  27. --
  28.  
  29. --
  30. -- Filtros para la tabla `materiasxcurso`
  31. --
  32. ALTER TABLE `materiasxcurso`
  33.   ADD CONSTRAINT `materiasxcurso_ibfk_2` FOREIGN KEY (`materia`) REFERENCES `materias` (`codigo`) ON DELETE CASCADE ON UPDATE CASCADE,
  34.   ADD CONSTRAINT `materiasxcurso_ibfk_1` FOREIGN KEY (`curso`) REFERENCES `cursos` (`codigo`) ON DELETE CASCADE ON UPDATE CASCADE;

Y finalmente, cada alumno debe tener un registro de que materias curso y que notas parciales se saco:
Código MySQL:
Ver original
  1. --
  2. -- Estructura de tabla para la tabla `materiasxalumno`
  3. --
  4.  
  5. CREATE TABLE IF NOT EXISTS `materiasxalumno` (
  6.   `alumno` int(10) unsigned NOT NULL,
  7.   `materia` int(10) unsigned NOT NULL,
  8.   `parcial1` tinyint(4) DEFAULT NULL,
  9.   `parcial2` tinyint(4) DEFAULT NULL,
  10.   `parcial3` tinyint(4) DEFAULT NULL,
  11.   PRIMARY KEY (`alumno`,`materia`),
  12.   KEY `materia` (`materia`)
  13.  
  14. --
  15. -- Volcado de datos para la tabla `materiasxalumno`
  16. --
  17.  
  18. INSERT INTO `materiasxalumno` (`alumno`, `materia`, `parcial1`, `parcial2`, `parcial3`) VALUES
  19. (1, 1, 10, 8, 9),
  20. (1, 2, 7, 8, 9),
  21. (2, 1, 4, 2, 6),
  22. (2, 2, 8, 7, 7),
  23. (3, 1, 2, 8, 9),
  24. (3, 2, 7, 7, 7),
  25. (4, 1, 7, 8, 7),
  26. (4, 2, 6, 8, 7),
  27. (4, 3, 5, 8, 8),
  28. (4, 4, 8, 7, 9),
  29. (5, 1, 7, 7, 7),
  30. (5, 2, 7, 7, 7),
  31. (5, 3, 4, 6, 6),
  32. (5, 4, 6, 8, 7),
  33. (6, 1, 6, 8, 8),
  34. (6, 2, 9, 6, 7),
  35. (6, 3, 1, 4, 6),
  36. (6, 4, 9, 8, 9);
  37.  
  38. --
  39. -- Restricciones para tablas volcadas
  40. --
  41.  
  42. --
  43. -- Filtros para la tabla `materiasxalumno`
  44. --
  45. ALTER TABLE `materiasxalumno`
  46.   ADD CONSTRAINT `materiasxalumno_ibfk_2` FOREIGN KEY (`materia`) REFERENCES `materias` (`codigo`) ON DELETE CASCADE ON UPDATE CASCADE,
  47.   ADD CONSTRAINT `materiasxalumno_ibfk_1` FOREIGN KEY (`alumno`) REFERENCES `alumnos` (`cedula`) ON DELETE CASCADE ON UPDATE CASCADE;

Ahora bien, con esa estructura, si lo que quieres es saber el promedio que un alumno tiene en una materia particular puedes hacer:
Código MySQL:
Ver original
  1.   a.nombre,
  2.   m.nombre,
  3.   (
  4.     (
  5.       IFNULL(ma.parcial1,0)+
  6.       IFNULL(ma.parcial2,0)+
  7.       IFNULL(ma.parcial3,0)
  8.     )
  9.     /
  10.     (
  11.       IF(ma.parcial1 IS NULL, 0, 1)+
  12.       IF(ma.parcial2 IS NULL, 0, 1)+
  13.       IF(ma.parcial3 IS NULL, 0, 1)
  14.     )
  15.   ) promedio
  16. FROM materiasxalumno ma
  17.   INNER JOIN alumnos a ON ma.alumno = a.cedula
  18.   INNER JOIN materias m ON ma.materia = m.codigo
  19.   (
  20.     ma.parcial1 IS NOT NULL OR
  21.     ma.parcial2 IS NOT NULL OR
  22.     ma.parcial3 IS NOT NULL
  23.   )
  24.   AND ma.alumno = 1
  25.   AND ma.materia = 1

Con eso sabes que promedio tiene un alumno en una materia.

Ahora si quieres saber el promedio de un alumno en todas las materias que curso, puedes hacer:
Código MySQL:
Ver original
  1.   a.nombre,
  2.   COUNT(ma.materia) materias_cursadas,  
  3.   AVG(
  4.     (
  5.       IFNULL(ma.parcial1,0)+
  6.       IFNULL(ma.parcial2,0)+
  7.       IFNULL(ma.parcial3,0)
  8.     )
  9.     /
  10.     (
  11.       IF(ma.parcial1 IS NULL, 0, 1)+
  12.       IF(ma.parcial2 IS NULL, 0, 1)+
  13.       IF(ma.parcial3 IS NULL, 0, 1)
  14.     )
  15.    ) promedio
  16. FROM materiasxalumno ma
  17.   INNER JOIN alumnos a ON ma.alumno = a.cedula
  18.   INNER JOIN materias m ON ma.materia = m.codigo
  19.   (
  20.     ma.parcial1 IS NOT NULL OR
  21.     ma.parcial2 IS NOT NULL OR
  22.     ma.parcial3 IS NOT NULL
  23.   )
  24.   AND ma.alumno = 1
  25. GROUP BY ma.alumno

Si quieres hacer un ranking puedes hacer:
Código MySQL:
Ver original
  1.   (@rownum:=@rownum+1) posicion,
  2.   ma.alumno,
  3.   a.nombre,
  4.   COUNT(ma.materia) materias_cursadas,  
  5.   AVG(
  6.     (
  7.       IFNULL(ma.parcial1,0)+
  8.       IFNULL(ma.parcial2,0)+
  9.       IFNULL(ma.parcial3,0)
  10.     )
  11.     /
  12.     (
  13.       IF(ma.parcial1 IS NULL, 0, 1)+
  14.       IF(ma.parcial2 IS NULL, 0, 1)+
  15.       IF(ma.parcial3 IS NULL, 0, 1)
  16.     )
  17.    ) promedio
  18.   (SELECT @rownum:=0) pos,
  19.   materiasxalumno ma
  20.   INNER JOIN alumnos a ON ma.alumno = a.cedula
  21.   INNER JOIN materias m ON ma.materia = m.codigo
  22.   (
  23.     ma.parcial1 IS NOT NULL OR
  24.     ma.parcial2 IS NOT NULL OR
  25.     ma.parcial3 IS NOT NULL
  26.   )
  27. GROUP BY ma.alumno
  28. ORDER BY promedio DESC

Y si quieres saber, en particular, que posicion de ese ranking ocupa un alumno, puedes hacer:
Código MySQL:
Ver original
  1. SELECT posicion
  2. (
  3.   (@rownum:=@rownum+1) posicion,
  4.   ma.alumno,
  5.   a.nombre,
  6.   COUNT(ma.materia) materias_cursadas,  
  7.   AVG(
  8.     (
  9.       IFNULL(ma.parcial1,0)+
  10.       IFNULL(ma.parcial2,0)+
  11.       IFNULL(ma.parcial3,0)
  12.     )
  13.     /
  14.     (
  15.       IF(ma.parcial1 IS NULL, 0, 1)+
  16.       IF(ma.parcial2 IS NULL, 0, 1)+
  17.       IF(ma.parcial3 IS NULL, 0, 1)
  18.     )
  19.    ) promedio
  20.   (SELECT @rownum:=0) pos,
  21.   materiasxalumno ma
  22.   INNER JOIN alumnos a ON ma.alumno = a.cedula
  23.   INNER JOIN materias m ON ma.materia = m.codigo
  24.   (
  25.     ma.parcial1 IS NOT NULL OR
  26.     ma.parcial2 IS NOT NULL OR
  27.     ma.parcial3 IS NOT NULL
  28.   )
  29. GROUP BY ma.alumno
  30. ORDER BY promedio DESC
  31. ) ranking
  32. ranking.alumno = 5
__________________
Maratón de desafíos PHP Junio - Agosto 2015 en FDW | Reglamento - Desafios

Última edición por NSD; 01/12/2014 a las 10:26