Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

GROUP BY Me los agrupa todos, no delimita

Estas en el tema de GROUP BY Me los agrupa todos, no delimita en el foro de Mysql en Foros del Web. Hola a todos, hace tiempo hice un tema donde intentaba hacer lo mismo, pero no he podido, me disculpan si tenia que continuar con el ...
  #1 (permalink)  
Antiguo 05/06/2012, 03:59
 
Fecha de Ingreso: noviembre-2008
Mensajes: 77
Antigüedad: 15 años, 6 meses
Puntos: 8
GROUP BY Me los agrupa todos, no delimita

Hola a todos, hace tiempo hice un tema donde intentaba hacer lo mismo, pero no he podido, me disculpan si tenia que continuar con el tema viejo. Debo sacar los promedios y los puestos de los alumnos, el periodo pasado tocó hacerlo manualmente porque no fué capaz (En este no quiero que sea así).

Creé vista como me aconsejaron aqui:

Código:
CREATE or replace VIEW `vistanotascalculadas` AS select `n`.`idAlumno` AS`idAlumno`,
`a`.`NombresAlum` AS `NombresAlum`,`mg`.`idMaterGrupo` AS `idMaterGrupo`,
`c`.`idCompet` AS `idCompet`,`i`.`Indicador` AS `Indicador`,`i`.`idIndic` AS `idIndic`,
`ga`.`idPeriodo` AS `idPeriodo`,`g`.`idGrupo` AS `idGrupo`,
`g`.`NombreGrupo` AS `NombreGrupo`,
((((`c`.`PorcCompet`* `i`.`PorcIndic`) / 100) * `n`.`Nota` )/100)  AS `NotaDeMateria` 
from ((((((`tbnotas` `n` 
join `tbindicadores` `i`) 
join `tbcompetencias` `c`) 
join `tbmateriagrupo` `mg`) 
join `tbalumnos` `a`) 
join `tbgrupoalumnos` `ga`) 
join `tbgrupos` `g`) 
where ((`n`.`idIndic` = `i`.`idIndic`) 
and (`i`.`CompetenciaIndic` = `c`.`idCompet`) 
and (`mg`.`idMaterGrupo` = `c`.`MateriaGrupoCompet`) 
and (`a`.`idAlum` = `n`.`idAlumno`) 
and (`mg`.`idGrupo` = `g`.`idGrupo`) 
and (`g`.`idGrupo` = `ga`.`idGrupo`) 
and (`ga`.`idAlumno` = `a`.`idAlum`)) 
order by `n`.`idAlumno`
NotaDeMateria es lo que necesito que se sume por materia (idMaterGrupo), y luego lo promedio para sacar el puntaje final del alumno. Lo hago así en php:

Código:
$sqlMat="select idAlumno, NombresAlum, idMaterGrupo, SUM(NotaDeMateria) AS PromMater 
from `vistanotascalculadas`
where idAlumno=".$rSqlAl['idAlumno']." and idPeriodo=".$_SESSION['PeriodoUsu']."
GROUP BY idMaterGrupo";
Aquí es donde me agrupa sumando todas las NotaDeMateria sin hacer distinción de periodo Sin embargo me doy cuenta que no debo tener una vista así pues cada periodo se está multiplicando de forma terrible con todas las notas existentes. Así que opté por hacer una vista por periodo:



Código:
CREATE or replace VIEW `vistanotascalculadasper1` AS 
SELECT `n`.`idAlumno` AS`idAlumno`, `a`.`NombresAlum` AS `NombresAlum`,
`mg`.`idMaterGrupo` AS `idMaterGrupo`, `c`.`idCompet` AS `idCompet`,`i`.`Indicador` AS `Indicador`,
`i`.`idIndic` AS `idIndic`, `ga`.`idPeriodo` AS `idPeriodo`,`g`.`idGrupo` AS `idGrupo`, 
`g`.`NombreGrupo` AS `NombreGrupo`, 
((((`c`.`PorcCompet`* `i`.`PorcIndic`) / 100) * `n`.`Nota` )/100) AS `NotaDeMateria` 
from ((((((`tbnotas` `n` 
join `tbindicadores` `i`) 
join `tbcompetencias` `c`) 
join `tbmateriagrupo` `mg`) 
join `tbalumnos` `a`) 
join `tbgrupoalumnos` `ga`) 
join `tbgrupos` `g`) 
where ((`n`.`idIndic` = `i`.`idIndic`) 
and (`i`.`CompetenciaIndic` = `c`.`idCompet`) 
and (`mg`.`idMaterGrupo` = `c`.`MateriaGrupoCompet`) 
and (`a`.`idAlum` = `n`.`idAlumno`) 
and (`mg`.`idGrupo` = `g`.`idGrupo`) 
and (`g`.`idGrupo` = `ga`.`idGrupo`) 
and (`ga`.`idAlumno` = `a`.`idAlum`) 
) AND `idPeriodo`=1 
order by `n`.`idAlumno`
Luego con php:

Código:
$sqlMat="select idAlumno, NombresAlum, idMaterGrupo, SUM(NotaDeMateria) AS PromMater 
from `vistanotascalculadasper".$_SESSION['PeriodoUsu']."`
where idAlumno=".$rSqlAl['idAlumno']." 
GROUP BY idMaterGrupo";
vistanotascalculadasper1 no me hace distinción entre periodos tampoco, ¿Cómo hago para hacer una vista por periodo y sacar los puestos?(Esto es lo q necesito).

La primera vista, aunque ya no me parece una opción, me gustaría que me explicaran por qué no agrupa por periodo, pues la trabajé mucho y no entiendo porqué me agrupa sin tener en cuenta el periodo.
  #2 (permalink)  
Antiguo 05/06/2012, 04:03
 
Fecha de Ingreso: noviembre-2008
Mensajes: 77
Antigüedad: 15 años, 6 meses
Puntos: 8
Respuesta: GROUP BY Me los agrupa todos, no delimita

Ah, por si acaso les digo q tbgrupoalumnos tiene el alumno, grupo y periodo. En tbmateriagrupo están las materias de los tbgrupos; tbcompetencias tiene el id de la materia a la que pertenece, tbindicadores tiene el id de la competencia a la que pertenece; y tbnotas tiene: el codigo del estudiante, el id del indicador al que pertenece y la Nota. Muchas gracias espero seguir aprendiendo con ustedes.
  #3 (permalink)  
Antiguo 05/06/2012, 05:12
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: GROUP BY Me los agrupa todos, no delimita

Cita:
...
tbgrupoalumnos tiene el alumno, grupo y periodo

tbmateriagrupo están las materias de los tbgrupos

tbcompetencias tiene el id de la materia a la que pertenece

tbindicadores tiene el id de la competencia a la que pertenece

tbnotas tiene: el codigo del estudiante, el id del indicador al que pertenece y la Nota
...
Para poder ayudarte deberías postear los campos concretos de todas las tablas y sus relaciones, postea el resultado de

SHOW CREATE TABLE nombreTabla

para cada tabla.

Con lo que nos dices yo diria que en la tabla tbnotas falta el periodo para que esto pueda funcionar .... o es que los alumnos son distintos en cada perido?


Para que te diferencie Alumnos periodos y materias debes indicarlo en el GROUP BY....

GROUP BY idPeriodo,idAlumno,idMaterGrupo";

y entre las funciones de agregado esta AVG que directamente te darà la nota promedio del alumno....

12.15.1. GROUP BY (Aggregate) Functions
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 05/06/2012 a las 05:39
  #4 (permalink)  
Antiguo 05/06/2012, 09:28
 
Fecha de Ingreso: noviembre-2008
Mensajes: 77
Antigüedad: 15 años, 6 meses
Puntos: 8
Respuesta: GROUP BY Me los agrupa todos, no delimita

Hola, aqui están las tablas básicas, espero lo entiendan y de pronto le sirva a alguien.



Hasta el momento creo que no hace falta nada, pues el periodo lo define tbgrupoalumnos, aunque ahora que lo pienso no he tomado en cuenta que tbcompetencias tambien tiene el periodo, no sé si por ai vaya el maní.

Lo de group by lo he usado así, pero igual me suma todos sin hacer distinción de periodos, pero como dije, no habia tomado en cuenta el tbcompetencias.idPeriodo

Gracias por seguirme ayudando.
  #5 (permalink)  
Antiguo 05/06/2012, 11:38
Avatar de 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, 5 meses
Puntos: 2658
Respuesta: GROUP BY Me los agrupa todos, no delimita

Cita:
La primera vista, aunque ya no me parece una opción, me gustaría que me explicaran por qué no agrupa por periodo, pues la trabajé mucho y no entiendo porqué me agrupa sin tener en cuenta el periodo.
Mira, uno de los problemas que tienes es que estás ordenando en una vista, cosa que no tiene mucho sentido a menos que uses la vista en "crudo", es decir, que la invoques como está y sn cambiar nada.
El ORDER BY y el GROUP BY son las cláusulas menos performánticas, y que sólo se deben usar donde y cuando se las necesite realmente.
Y no es en este punto.
¿Qué sentido tiene ordenar en una vista, para luego ordenar cuando llamas a la vista?

El segundo problema es que no conoces el funcionamiento del GROUP BY en MySQL, el cual tiene algunas diferencias bastante críticas.
Por empezar, cuando haces un agrupamiento simple sobre una tabla, es decir, sobre un sólo campo, tienes que tener en cuenta que MySQL simplificará el resultado y te devolverá el primer registro que encuentre con cada valor distinto sobre ese campo.
Este detalle implica que si tuvieses 30 valores de un campo, donde el mayor fuese el 7°, y el menor el primero, si agrupas directamente sobre otro campo, te devolverá el registro que primero encuentre: El del menor valor.
¿Se entiende?
Entonces, como el ORDER BY se aplica sobre el resultado de un GROUP BY (y no al revés), ese GROUP BY puede "esconder" valores antes del ordenamiento.
La única solución es:
1) La vista no debe ser ordenada.
2) Primer indicas el criterio de agrupamiento al invocar a la vista, incluyendo (como dice quimfv) todos los campos que actúan de datos base.
3) Ese SELECT debe generar una tabla derivada, a la cual se le aplica el ORDER BY.

En definitiva quedaría mas o menos así (ejemplo):
Código MySQL:
Ver original
  1. CREATE OR REPLACE VIEW vistanotascalculadas
  2.     `n`.`idAlumno`,
  3.     `a`.`NombresAlum`,
  4.     `mg`.`idMaterGrupo`,
  5.     `c`.`idCompet`,
  6.     `i`.`Indicador`,
  7.     `i`.`idIndic`,
  8.     `ga`.`idPeriodo`,
  9.     `g`.`idGrupo`,
  10.     `g`.`NombreGrupo`,
  11.     ((((`c`.`PorcCompet`* `i`.`PorcIndic`) / 100) * `n`.`Nota` )/100)  `NotaDeMateria`
  12.     tbnotas n INNER JOIN tbindicadores i ON `n`.`idIndic` = `i`.`idIndic`
  13.     INNER JOIN `tbcompetencias` `c` ON `i`.`CompetenciaIndic` = `c`.`idCompet`
  14.     INNER JOIN `tbmateriagrupo` `mg` ON `mg`.`idMaterGrupo` = `c`.`MateriaGrupoCompet` AND
  15.     INNER JOIN `tbalumnos` `a` ON `a`.`idAlum` = `n`.`idAlumno`
  16.     INNER JOIN `tbgrupoalumnos` `ga` ON `ga`.`idAlumno` = `a`.`idAlum`
  17.     INNER JOIN `tbgrupos` `g` ON `mg`.`idGrupo` = `g`.`idGrupo` AND `g`.`idGrupo` = `ga`.`idGrupo`;

Y luego la llamas:
Código MySQL:
Ver original
  1.     IDALUMNO,
  2.     NOMBRESALUM,
  3.     idGrupo,
  4.     IDMATERGRUPO,
  5.     PROMMATER
  6.     (SELECT
  7.         idAlumno,
  8.         NombresAlum,
  9.         idMaterGrupo,
  10.         idGrupo,
  11.         SUM(NotaDeMateria) PromMater
  12.     FROM `vistanotascalculadasper`
  13.     GROUP BY IDALUMNO, idMaterGrupo) T1
  14. ORDER BY idGrupo, idMaterGrupo;

Un detalle adicional: No tiene ningún sentido ni es buena performance crear una vista para cada sesión, persona, grupo, etc.
Es una pésima práctica que te puede llevar a perder el control de los objetos que hay en la base.
Lo que se hace es crear una vista con los datos necesarios para poder filtrarla y obtener el segmento de datos deseado.
¿Se comprende la idea?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 27/06/2012, 06:19
 
Fecha de Ingreso: noviembre-2008
Mensajes: 77
Antigüedad: 15 años, 6 meses
Puntos: 8
Respuesta: GROUP BY Me los agrupa todos, no delimita

Muchisimas gracias, estuve intentando aplicar todo lo que me estan diciendo, y por fin encontré que debo ser muy detallado a la hora de relacionar tablas, pues me traia una multiplicacion o notas que no eran del grupo. Estoy muy feliz, he aprendido mucho y lo mejor.... solucioné el problema, y es realmente gracias a toda la informacion que ustedes me dieron, mil gracias.

gnzsoloyo, workbench me creaba el order by, y por cuestiones de probar la consulta interna, y luego la externa, era necesario ponerlo o dejarlo, aunque sé que no sirve de nada en el resultado final.

Dios los guarde mucho.
  #7 (permalink)  
Antiguo 27/06/2012, 07:07
Avatar de 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, 5 meses
Puntos: 2658
Respuesta: GROUP BY Me los agrupa todos, no delimita

Cita:
gnzsoloyo, workbench me creaba el order by (...)
Eso es algo que pasa con cualquier software de este tipo. Cuando usas los asistentes siempre le agregan cosas que son consideradas "estándar",pero que en realidad terminan siendo basura.
Lo que se suele hacer (al menos yo lo hago), es usar el asistente para acelerar la creación de la consulta y hacerlo de un modo "amigable", pero luego esa consulta obtenida jamás se debería usar como está, sino que hay que hacerle ajustes tales como borrarle el código irrelevante (los AS, algunos paréntesis, etc.), y quitarle lo que no necesita (como los ORDER BY, GROUP BY) cuando no es parte del diseño buscado.
Siempre hay que tocar algo del código obtenido. A fin de cuentas, no pretenderás que algo estándar sirva sin correcciones para usos específicos...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: group, join, php, select, sql
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 09:32.