Foros del Web » Programando para Internet » PHP »

while PHP sumar valor de de un id identico

Estas en el tema de while PHP sumar valor de de un id identico en el foro de PHP en Foros del Web. Acudo a ustedes porque siempre me han tenido una solucion, espero esta vez tambien encontrar la solucion, el problema es le siguiente Código PHP: //selecciono un rango de distintos ci_be por fechas ...
  #1 (permalink)  
Antiguo 04/05/2006, 15:58
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
while PHP sumar valor de de un id identico

Acudo a ustedes porque siempre me han tenido una solucion, espero esta vez tambien encontrar la solucion, el problema es le siguiente
Código PHP:
//selecciono un rango de distintos ci_be por fechas
$result BDConexion("select ci_be from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy'") or die($error_conex);
while(
$r mysql_fetch_array($result)){
$ci_be $r['ci_be']; //numero de identificacion, si se repite en la siguiente consulta quiero sumar el monto_oc_dls, el monto_oc_dls contine un valor en dolares
$result2 BDConexion("select ci_be,monto_oc_dls from solicitud WHERE ci_be='$ci_be'") or die($error_conex);

if(
mysql_num_rows($result2) > 1) {
     
$us_ci_be mysql_fetch_array($result2);
    
$ci_be $us_ci_be['ci_be']; 

    echo 
$ci_be."<br>";
    
}

puedo ver cuantas veces se repite el ci_be, cada ci_be contiene tambien un monto_oc_dls, lo que quiero es que si el ci_be se repite que se sumen los valores de monto_oc_dls por cada ci_be, hay distintos ci_be y a veces se repiten, solo si se repiten, identificarlos y luego sumar monto_oc_dls.
  #2 (permalink)  
Antiguo 04/05/2006, 16:49
 
Fecha de Ingreso: junio-2002
Mensajes: 750
Antigüedad: 21 años, 10 meses
Puntos: 22
Quizás lo puedes realizar en una sola consulta, sin tener que recorrer todo el array y realizar cada vez una consulta por ci_be:

Código PHP:
$result BDConexion("select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be") or die($error_conex);

if(
mysql_num_rows($result) > 0) {
  while(
$r mysql_fetch_array($result)){
    echo 
$r['ci_be'] . ' = ' $r['sum_monto'] . ' Dolares<br/>';
  }

Salu2
  #3 (permalink)  
Antiguo 04/05/2006, 16:58
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Entiendo lo que dices pero si te fijas en ningun momento estarias conprobando si ci_be se repite para asi sumar los monto_dls
  #4 (permalink)  
Antiguo 04/05/2006, 17:36
 
Fecha de Ingreso: junio-2002
Mensajes: 750
Antigüedad: 21 años, 10 meses
Puntos: 22
Estaría sumando los montos totales de cada ci_be. No se si es eso lo que quieres o entendí mal...
  #5 (permalink)  
Antiguo 05/05/2006, 15:39
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Eres un genio

Si funciono tu codigo anterior a la perfeccion, solo tengo una duda para que sirve el sum() se encargará de sumar todo lo que agrupas?
  #6 (permalink)  
Antiguo 05/05/2006, 17:09
 
Fecha de Ingreso: junio-2002
Mensajes: 750
Antigüedad: 21 años, 10 meses
Puntos: 22
Exacto. Suma todos los campos que coincidan con el criterio de selección (en este caso suma el contenido de todos los registros donde aparezca el mismo ci_be) gracias a la agrupación realizada.

Salu2
  #7 (permalink)  
Antiguo 06/05/2006, 09:33
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Otra duda

Al hacer el sum() me he dado cuenta que suma incluco si hay solo un solo ci_be, el problema pienso que se generaria al realizar una consulta en muchos registros y creo que se haria poco lento procesar muchos registros, habra como decirle en la misma consulta que solo sume si el monto_oc_dls es mayor a 5000? , o que seleccione solo a los que son mayores a 5000 y que sume solo esos?
  #8 (permalink)  
Antiguo 06/05/2006, 10:13
Avatar de chiviwalker  
Fecha de Ingreso: marzo-2004
Ubicación: Alicante
Mensajes: 55
Antigüedad: 20 años, 1 mes
Puntos: 0
Bueno no soy muy experto pero creo q eso se puede hacer con "having":

Código:
("select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be HAVING monto_oc_dls > 5000")
Saludos.
  #9 (permalink)  
Antiguo 07/05/2006, 20:42
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Para seleccionar solo los que tiene mas de 5000 hice lo que veras a continuación no se si es lo mejor que hecho, existe alguna forma de optimizar el código?, ahora lo que deseo que si existe por lo menos uno con mas de 5000 o 2 o los que haya, almacenarlos en una nueva tabla llamada transac_inu tomando en cuenta que solo insertaré los que tengan un nuevo ci_be, si el ci_be ya existe y se encuentra en el rango de fechas, en la nueva tabla solo actualizaré el sum_monto.

Este es el código que tengo pero no hallo forma de hacerlo funcionar correctamente, denme una mano por favor. Por cierto el having que se mensiona en el comentario anterior por chiviwalker aun no lo pruebo, si eso otimiza lo que tengo házmelo saber.

Código PHP:

$result 
BDConexion("select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be") or die($error_conex);

if(
mysql_num_rows($result) > 0) {
  while(
$r mysql_fetch_array($result)){
        
      if(
$r['sum_monto'] > 4999){
          
$trans_num $trans_num 1;
        
        
$ci_be    $r['ci_be'];
        
$monto_be    $r['sum_monto'];
       }
        
$result_tran BDConexion("select * from transac_inu") or die($error_conex);
        
$r_tran mysql_fetch_array($result_tran);
        
$id_tran    $r_tran['id_transac_inu'];
        
$fecha_tran     $r_tran['fecha'];
        
$ci_be_tran    $r_tran['ci_be'];
        
        
mysql_free_result($result_tran);
        
//// Actualizo transacción si es el mismo mes y el mismo ci_be y si es un monto distinto
        
if($fecha_ant == $fecha_tran && $monto_be != $r_tran['sum_monto'] && $ci_b  == $ci_be_tran){
        
                
$up_tran['sum_monto'] = $monto_be;
                
BDUpdate('transac_inu'$up_tran$id_tran) or die($error_conex);
        }
  }


Última edición por cyberbot; 08/05/2006 a las 14:05
  #10 (permalink)  
Antiguo 08/05/2006, 14:10
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Me olvide de algo

Por cierto cuando hago correr mi codigo lo unico que funciona correctamente es el update a la base de datos el resto nada, por favor denme una ayuda
  #11 (permalink)  
Antiguo 08/05/2006, 15:49
 
Fecha de Ingreso: junio-2002
Mensajes: 750
Antigüedad: 21 años, 10 meses
Puntos: 22
Lo que dice chiviwalker
Cita:
select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be HAVING monto_oc_dls >= 5000
debería funcionar y si sólo necesitas los monto_oc_dls mayores de 4999 creo que es la manera más correcta y óptima de hacerlo.

En cuanto a la demora de las consultas, generalmente son bastante rápidas. Pero se puede notar una demora cuando el número de registros que debe consultar es elevado (no puedo especificar una cantidad fija para que eso ocurra, pero se sobreentiende que si ha de consultar 50000 registros puede demorar más que si únicamente consulta 3000, para obtener más información sobre el tiempo que tarda en ejecutar una consulta mysql dispone de algunos métodos, algunos de ellos hacen necesario el uso de la consola de mysql.)

Para más info sobre este tema busca "mysql benchmark" o accede a http://dev.mysql.com/tech-resources/benchmarks/


Para la actualización:

se podría intentar algo parecido a lo siguiente (ten en cuenta que no he comprobado su funcionamiento y no puedo asegurar que funcione. Antes de probarlo realiza una copia de seguridad de la base de datos.) No sé si la sintaxis empleada en la consulta es correcta o no es posible usar tal anidación de consultas y referencias a tablas con el método UPDATE. Si se puede realizar esta consulta, estoy seguro que existen formas de simplificar la consulta (con join, etc.)

Cita:
UPDATE transac_inu

SET sum_monto = (
SELECT sum_monto_solicitud FROM (
SELECT ci_be, SUM(monto_oc_dls) AS sum_monto_solicitud
FROM solicitud
WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy'
GROUP BY ci_be
HAVING monto_oc_dls >= 5000
) AS t1)

WHERE transac_inu.ci_be = t1.ci_be
Puede parecer complicado pero una vez funcione, puedes ver el potencial del uso de sql.

En caso de que la consulta te funcione (tal cual o modificada), para realizar un Insert solo hay que cambiar cuatro cosas.

Seguro que Cluster puede darte buenos consejos sobre este tema.

Disculpad que me haya extendido un poco en el texto.
  #12 (permalink)  
Antiguo 10/05/2006, 16:57
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
No funciona

Ya he probado de todas las formas que se me han ocurrido y el codigo que pones anteriormente no funciona sale error que no se puede conectar a la base de datos, en cuanto al having habia un error que ya corregi, el codigo erroneo es:

Código PHP:
("select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be HAVING monto_oc_dls > 5000"
Digo error porque donde se hace la comparacion mayor a 5000 es esta usando un campo que no existe ya que fue asignado a otro valor es decir a sum_monto, el codigo correcto seria.
Código PHP:
("select ci_be, sum(monto_oc_dls) as sum_monto from solicitud WHERE fecha_sys BETWEEN '$fecha_ant' AND '$fecha_hoy' group by ci_be HAVING sum_monto > 5000"
En cuanto a a mi solicitud aun estoy esperando haber si alguien o mis amigos de foros del web pueden darme una solucion, de todas formas agradesco su ayuda porque me ha sido muy util.
  #13 (permalink)  
Antiguo 14/05/2006, 12:50
 
Fecha de Ingreso: diciembre-2003
Ubicación: Guayaquil
Mensajes: 18
Antigüedad: 20 años, 3 meses
Puntos: 0
Alguien que pueda ayudarme

Por favor lo unico que necesito es que se inserten los datos automaticamente en una nueva tabla cada vez que haya una nueva suma mayor a 5000 y si el ci_be existe y esta en el mismo rango de fechas se actualice
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 06:32.