Ver Mensaje Individual
  #3 (permalink)  
Antiguo 19/11/2013, 13:31
leonardo_josue
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 4 meses
Puntos: 447
Respuesta: Problemas con el redondeo de mysql

Hola carlosml08:

Una pregunta: ¿por qué razón tienes que calcular el promedio de manera manual? ¿acaso tienes algún problema en utilizar la función AVG que está diseñada específicamente para obtener promedios?

Tu consulta en realidad es bastante rebuscada, pero al no ser una consulta simple puede resultar algo complicado entenderla, sobre todo sin saber qué datos almacenas en cada tabla, pero aquí algunas observaciones:

1. Estás mezclando dos formas de hacer uniones entre tablas, lo cual puede acarrearte en primer lugar problemas de productos cartesianos y en segundo lugar terribles problemas de rendimiento... existen dos formas de hacer JOIN's:

-> Listando las tablas en el FROM y haciendo las relaciones en el WHERE (JOIN EXPLÍCITO):

Código:
FROM tabla1, tabla2 WHERE tabla1.campo = tabla2.campo
-> Utilizando JOIN's (INNER, LEFT, RIGTH):

Código:
-> FROM tabla1 INNER JOIN tabla2 ON tabla1.campo = tabla2.campo:
En tu caso estás mezclando ambas formas, ya que por un lado pones JOIN, pero en ningún caso colocas la cláusula ON... tal como lo haces se está realizando un producto cartesiano entre tus tablas, aunque al filtrar en el WHERE el resultado sea 'correcto'. Además, haces un uso completamente inútil de paréntesis, estos en realidad no te sirven para nada

La consulta debería quedar así:

Código MySQL:
Ver original
  1.         `nota`.`upclass_id` AS `upclass_id`,
  2.         `g`.`grade` AS `grade`,
  3.         `c`.`class_name` AS `class_name`,
  4.         `nota`.`cal_id` AS `cal_id`,
  5.         sum((`nota`.`grade` * `rc`.`weightings`)) / (select  
  6.                         sum(`rule_comment`.`weightings`)
  7.                     from
  8.                         `rule_comment`
  9.                     where
  10.                         (`rule_comment`.`actives` = 'true')) AS `promedio`,
  11.         `nota`.`student_id` AS `student_id`
  12.     from
  13.        `student_subject_grade` `nota`  
  14.        join `subject` `sub` ON `nota`.`subject_id` = `sub`.`id`
  15.        join  `sy` `s` ON `sub`.`sy_id` = `s`.`id`
  16.        join `rule_comment` `rc` ON `rc`.`subject_id` = `sub`.`id`
  17.        join `term_cal` `cal` ON `nota`.`cal_id` = `cal`.`id`
  18.        join `upclass` `c` ON `c`.`id` = `nota`.`upclass_id`
  19.        join `grade` `g` `g`.`id` = `c`.`grade_id`
  20.     where
  21.        `cal`.`active` = 'true'
  22.        and `cal`.`release_cal` = 'true'
  23.     group by `cal`.`id` , `nota`.`student_id`
  24.     order by `nota`.`student_id` , `cal`.`id`

Otro detalle... el hacer la subconsulta en el SELECT, es también completamente ineficiente, ya que estás obligando a hacer una consulta por cada registro... si tu tabla es muy grande imagina cuanto puede tardar la consulta... además, por lo que veo, esta consulta no varia con respecto del registro en cuestión, es decir, SIEMPRE VALE LO MISMO, entonces, ¿qué caso tiene que tengas que calcular cada vez este total?

Código MySQL:
Ver original
  1. (select  
  2.     sum(`rule_comment`.`weightings`)
  3.  from
  4.     `rule_comment`
  5.     (`rule_comment`.`actives` = 'true'))

Si en realidad ocupas obtener este valor, es mejor que ejecutes en una consulta previa esta consulta y almacenes el resultado en una variable temporal, y utilizar esa variable en la consulta de arriba, de tal manera que no tengas que ejecutar cada vez este calculo... puedes hacerlo en un SP o buscar alguna otra alternativa... ahí puede estar el error, más que un problema con el redondeo.

Finalmente, puedes postear algunos datos de ejemplo para ver qué estás obteniendo y qué es lo que quieres obtener, igual y podemos proponerte una mejor opción para realizar el cálculo.

Saludos
Leo.