Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   PHP (https://www.clubdelphi.com/foros/forumdisplay.php?f=15)
-   -   PHP – MYSQL: Sumar importes agrupando por meses y separando los años (https://www.clubdelphi.com/foros/showthread.php?t=93347)

Jose Manuel 11-08-2018 14:28:41

PHP – MYSQL: Sumar importes agrupando por meses y separando los años
 
Hola, estoy empezando con una web donde necesito mostrar en una tabla, los importes acumulados por meses de 2 años.

-------------------------------------
|mes | gasto 2017 | gasto 2018 |
------------------------------------
|ENERO | 1.255,50 | 1.750,70 |
------------------------------------
|FEBRERO | 3.444,50 | 3.222,20 |
------------------------------------
|MARZO | 1.544,20 | 0,0 |
------------------------------------

Con esta instrucción obtengo los datos de un año, pero no veo los 2 año juntos

Código PHP:

$select=$db->prepare('
SELECT Month(f_fecha) as Month, sum(n_importe) as n_importe FROM contabilidad WHERE YEAR(f_fecha) = 2017 and n_importe<0 Group By Month'
)    ;
$select->execute();    
foreach (
$select as $row) {
echo 
"<tr>"
echo 
"<td>" $row['Month'] . "</td>";
echo 
"<td>" .number_format($row['n_importe'], 2',''.')."</td>";
echo 
"<td>" .number_format($row['n_importe2'], 2',''.')."</td>";   // aquí debería ir la suma del año 2018

echo "</tr>";     
}            
echo 
"</tr>";        
echo 
"</table>";    
echo 
"</div>";    
?> 


Casimiro Notevi 11-08-2018 18:06:35

Cita:

Empezado por Jose Manuel (Mensaje 528030)
pero no veo los 2 año juntos

¿Juntos? ¿uno al lado del otro o sumados ambos?
Porque, obviamente, con ese select estás sacando solamente los del año 2017
Código SQL [-]
SELECT Month(f_fecha) as Month, sum(n_importe) as n_importe 
FROM contabilidad 
WHERE YEAR(f_fecha) = 2017 
and n_importe<0 
Group By Month

Jose Manuel 11-08-2018 19:10:16

Lo que pretendo es hacer una tabla que muestre los importes de 12 meses y 2 años. Efectivamente el ejemplo del SELECT solo me muestra un año, he intentado hacerlo con UNION y otras formas, pero no me sale.

Mi pregunta es, partiendo de un tabla donde se guardan todos los apuntes contables, se puede mostrar esa información directamente, o debo hacerlo con arrays, primero pasando un año y luego el otro.

Gracias y un saludo.

Casimiro Notevi 11-08-2018 22:37:40

Pues depende de cómo estén guardados esos datos, pero si no pones la estructura de la tabla, poco podemos adivinar.

Casimiro Notevi 11-08-2018 23:22:52

Tratando de adivinar, más o menos puede servirte algo así:
Código SQL [-]
select sum(saldo), extract(month from fechaasiento), ejercicio
from tbApuntes
where ejercicio=2016
group by extract(month from fechaasiento), ejercicio
union all
select sum(saldo), extract(month from fechaasiento), ejercicio
from tbApuntes
where ejercicio=2017
group by extract(month from fechaasiento), ejercicio

Jose Manuel 12-08-2018 09:51:48

Gracia por tu respuesta,

Esta instrucción, es similar a una de las que he probado.

Código PHP:

$select=$db->prepare('
SELECT MonthName(f_fecha) as Month, year(f_fecha) as Year, sum(n_importe) as n_importe 
FROM contabilidad  
Group By YEAR(f_fecha), Month(f_fecha)'
)    ; 

Creo que para obtener lo que quiero deberia incluir un subselect para que me creará el campo del año actual.

Pongo una imagen de lo que sale con ambas instrucciones y lo que yo quiero conseguir.



muestro el codigo y la tabla donde quiero ponerlo.
Código PHP:

$select=$db->prepare('
SELECT MonthName(f_fecha) as Month, year(f_fecha) as Year, sum(n_importe) as n_importe FROM contabilidad WHERE  n_importe<0 and year(f_fecha)=2017 Group By YEAR(f_fecha), Month(f_fecha)
union all
SELECT MonthName(f_fecha) as Month, year(f_fecha) as Year, sum(n_importe) as n_importe FROM contabilidad WHERE  n_importe<0 and year(f_fecha)=2018 Group By YEAR(f_fecha), Month(f_fecha)'
);
        
$select->execute();    
foreach (
$select as $row) {
echo 
"<tr>"
echo 
"<td>" $row['Month'] . "</td>";
echo 
"<td>" .number_format($row['n_importe'], 2',''.')."</td>";
echo 
"<td>" .number_format($row['n_importe2'], 2',''.')."</td>";    // me falta este campo
echo "</tr>";     



Casimiro Notevi 12-08-2018 10:17:48

Una búsqueda por 'pivot' te dará una idea de cómo es.

mamcx 12-08-2018 18:16:05

El problema de casi el 100% de todas las preguntas sobre SQL es la falta de los datos ORIGINALES. Siempre muestran el resultado, no de donde sale eso:

http://www.galeon.com/neoprogramadores/ch1taoup.htm

Cita:

Muéstrame tus diagramas de flujo y esconde tus tablas y continuaré desconcertado, muéstrame tus tablas y usualmente no necesitaré tus diagramas de flujo; ellos serán obvios.

The Mythical Man-Month / Fred Brooks

Casimiro Notevi 12-08-2018 19:19:05

Cita:

Empezado por mamcx (Mensaje 528039)
El problema de casi el 100% de todas las preguntas sobre SQL es la falta de los datos ORIGINALES. Siempre muestran el resultado, no de donde sale eso:

http://www.galeon.com/neoprogramadores/ch1taoup.htm

^\||/^\||/^\||/^\||/^\||/^\||/^\||/^\||/^\||/

Jose Manuel 13-08-2018 11:59:47

Hola, el origen de la consulta es que tengo una tabla llamada contabilidad, con la siguiente estructura

Código PHP:

CREATE TABLE `contabilidad` (
  `
n_idint(11NOT NULL,
  `
n_id_comunidadestinyint(4NOT NULL,
  `
n_id_gruposint(11NOT NULL,
  `
f_fechadate NOT NULL,
  `
c_conceptovarchar(150COLLATE utf8_unicode_ci NOT NULL,
  `
n_importedecimal(12,2NOT NULL,
  `
n_saldodecimal(12,2NOT NULL,
  `
f_registrodate NOT NULL
ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Esta tabla es un diario contable con registros de varios años, y lo que pretendía hacer con una consulta SQL era obtener el resumen de los gastos agrupado por meses del año actual y anterior, para mostrarlo en una tabla.

Al final lo conseguido pasando los resultados de las 4 consultas (GASTOS mensuales año actual, GASTOS mensuales año anterior, INGRESOS mensuales año actual, INGRESOS mensuales año anterior), a un Array() y después los he puesto en una tabla, el resultado es el de esta imagen.


El codigo PHP PDO que he utilizado es el siguiente:
Código PHP:

        <?php  
        $hoy 
getdate();       //array datos sistema para obtener el año.;
                
require_once('conexion.php');
        
$db=Db::conectar();    

        
// gastos año anterior
        
$select=$db->prepare('
        select Month(f_fecha) as Month, sum(n_importe) as n_importe from contabilidad WHERE YEAR(f_fecha) =:yearAnterior and n_importe<0 Group By Month'
);
        
$select->bindValue('yearAnterior',$hoy['year']-1);
        
$select->execute();        
        
$año_anterior $select->fetchAll(PDO::FETCH_ASSOC);

        
// gastos año actual        
        
$select=$db->prepare('
        select count(*), Month(f_fecha) as Month, sum(n_importe) as n_importe from contabilidad where YEAR(f_fecha) =:yearActual and n_importe<0 Group By Month'
);
        
$select->bindValue('yearActual',$hoy['year']);        
        
$select->execute();    
                
$año_actual $select->fetchAll(PDO::FETCH_ASSOC);    
        
$filas=$select->rowCount(); // obtenemos el nº de filas recibidas        
        // rellenamos con cero el array de los meses que no hay datos
        
for($i=$filas;$i<12;$i++) {    
        
$año_actual[$i]['Month']=$i;
                
$año_actual[$i]['n_importe']=0.00;        
        }       

        
// ingresos año anterior
        
$select=$db->prepare('
        select Month(f_fecha) as Month, sum(n_importe) as n_importe from contabilidad WHERE YEAR(f_fecha) =:yearAnterior and n_importe>=0 Group By Month'
);
        
$select->bindValue('yearAnterior',$hoy['year']-1);
        
$select->execute();        
        
$i_año_anterior $select->fetchAll(PDO::FETCH_ASSOC);
        
        
// ingresos año actual
        
$select=$db->prepare('
        select count(*), Month(f_fecha) as Month, sum(n_importe) as n_importe from contabilidad where YEAR(f_fecha) =:yearActual and n_importe>=0 Group By Month'
);
        
$select->bindValue('yearActual',$hoy['year']);        
        
$select->execute();    
                
$i_año_actual $select->fetchAll(PDO::FETCH_ASSOC);    
        
$filas=$select->rowCount(); // obtenemos el nº de filas recibidas        
        // rellenamos con cero el array de los meses que no hay datos
        
for($i=$filas;$i<12;$i++) {    
        
$i_año_actual[$i]['Month']=$i;
                
$i_año_actual[$i]['n_importe']=0.00;        
        }       
        echo 
"<div style='overflow-x:auto'>";
        echo 
"<table border='1' id='mitabla' >";
        echo 
"<thead>";
        echo 
"<tr>";
        echo 
"<th class='table-header' width='10%'>  </th>";
        echo 
"<th class='table-header' width='22%'>Gastos</th>";
        echo 
"<th class='table-header' width='22%'>Gastos</th>";
        echo 
"<th class='table-header' width='22%'>Ingresos</th>";
        echo 
"<th class='table-header' width='22%'>Ingresos</th>";        
        echo 
"</tr>";
        echo 
"</thead>";
            echo 
"<thead>";
        echo 
"<tr>";
        echo 
"<th>Mes</th>";
        echo 
"<th><div class='links'>              
              <a class='active' href='cta_bancaria.php'>"
.$hoy['year']."</a></th> </div>";    
        echo 
"<th><div class='links'>              
              <a class='active' href='cta_bancaria.php'>"
.($hoy['year']-1)."</a></th> </div>";
        echo 
"<th>".$hoy['year']."</th>";            
              echo 
"<th>".($hoy['year']-1)."</th>";
        echo 
"</tr>";
        echo 
"</thead>";   
            
                
$total_actual=0;
        
$total_anterior=0;    
                
$i_total_actual=0;
        
$i_total_anterior=0;    
        
$meses = array("-","Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre");
        
        for(
$i=0;$i<12;$i++) {    // recorremos el array. NOTA: debe haber datos en todos los items    
             
echo "<tbody>";
        echo 
"<tr>";
        echo 
"  <td> ".$meses[$año_anterior[$i]['Month']]."</td>";    
        
        echo 
"  <td ALIGN='right'> ".number_format($año_actual[$i]['n_importe'], 2',''.')."</td>";
        echo 
"  <td ALIGN='right'> ".number_format($año_anterior[$i]['n_importe'], 2',''.')."</td>";
        echo 
"  <td ALIGN='right'> ".number_format($i_año_actual[$i]['n_importe'], 2',''.')."</td>";
        echo 
"  <td ALIGN='right'> ".number_format($i_año_anterior[$i]['n_importe'], 2',''.')."</td>";
        echo 
"</tr>";    
            
        
$total_actual    $total_actual     $año_actual[$i]['n_importe'];
        
$total_anterior  $total_anterior   $año_anterior[$i]['n_importe'];
        
$i_total_actual  $i_total_actual   $i_año_actual[$i]['n_importe'];
        
$i_total_anterior$i_total_anterior $i_año_anterior[$i]['n_importe'];
            
        }        
        echo 
"<tr>";
                echo 
"  <td> TOTAL  </td>";        
        echo 
"  <td ALIGN='right'> ".number_format($total_actual2',''.')."</td>";                
        echo 
"  <td ALIGN='right'> ".number_format($total_anterior2',''.')."</td>";        
        echo 
"  <td ALIGN='right'> ".number_format($i_total_actual2',''.')."</td>";                
        echo 
"  <td ALIGN='right'> ".number_format($i_total_anterior2',''.')."</td>";        
        echo 
"</tr>";            
        
        echo 
"</tbody>";            
        echo 
"</tr>";                    
        echo 
"</table>";    
     echo 
"</div>";    
    
?>

No se si hay otra forma de realizarlo más eficaz, pero esta funciona bastante bien.

Un saludo y muchas gracias a todos.

Casimiro Notevi 13-08-2018 12:12:41

Cita:

Empezado por Jose Manuel (Mensaje 528046)
No se si hay otra forma de realizarlo más eficaz

Pues como te he indicado antes, con "pivot".


La franja horaria es GMT +2. Ahora son las 20:52:18.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi