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

Problemas con el redondeo de mysql

Estas en el tema de Problemas con el redondeo de mysql en el foro de Mysql en Foros del Web. Estoy calculando un promedio desde una consulta en mysql, pero al realizar el calculo manual no siempre calcula bien el promedio y el error me ...
  #1 (permalink)  
Antiguo 19/11/2013, 11:45
 
Fecha de Ingreso: septiembre-2013
Mensajes: 61
Antigüedad: 10 años, 7 meses
Puntos: 0
Problemas con el redondeo de mysql

Estoy calculando un promedio desde una consulta en mysql, pero al realizar el calculo manual no siempre calcula bien el promedio y el error me lo da por un decimal, he comprobado el calculo desde php con la libreria fpdf y de forma manual. Les adjunto la consulta:
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`)
  15.         join `rule_comment` `rc`)
  16.         join `sy` `s`)
  17.         join `term_cal` `cal`)
  18.         join `upclass` `c`)
  19.         join `grade` `g`)
  20.     where
  21.         ((`nota`.`subject_id` = `sub`.`id`)
  22.             and (`sub`.`sy_id` = `s`.`id`)
  23.             and (`rc`.`subject_id` = `sub`.`id`)
  24.             and (`nota`.`cal_id` = `cal`.`id`)
  25.             and (`cal`.`active` = 'true')
  26.             and (`cal`.`release_cal` = 'true')
  27.             and (`c`.`id` = `nota`.`upclass_id`)
  28.             and (`g`.`id` = `c`.`grade_id`))
  29.     group by `cal`.`id` , `nota`.`student_id`
  30.     order by `nota`.`student_id` , `cal`.`id`
[/PHP]
Tambien lo he probado redondeando el promedio con la funcion ROUND(n,2) y siempre el mismo resultado.

Última edición por gnzsoloyo; 19/11/2013 a las 13:15 Razón: MUY mal etiquetado. Usar Highlight correcto, por favor.
  #2 (permalink)  
Antiguo 19/11/2013, 13:17
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, 4 meses
Puntos: 2658
Respuesta: Problemas con el redondeo de mysql

La consulta sin los datos hace muy difícil de analizar si el error es real (no lo creo, MySQL no comete ese tipo de errores), o producto de un escenario determinado.
Postea un ejemplo de los datos que se calculan, cuál es lo que obtienes y qué es lo que se supone que deberías obtener, según estimas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 19/11/2013, 13:31
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 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.

Etiquetas: 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 19:16.