Foros del Web » Programando para Internet » PHP »

como puedo generar una tabla cruzada???

Estas en el tema de como puedo generar una tabla cruzada??? en el foro de PHP en Foros del Web. Saludos a todos.! Me encuetro en un problema al generar un reporte con 2 tablas: personal_catorcenald: sus campos son: id, Personal. la otra tabla es ...
  #1 (permalink)  
Antiguo 21/11/2012, 01:07
 
Fecha de Ingreso: octubre-2012
Ubicación: El Salvador
Mensajes: 14
Antigüedad: 11 años, 6 meses
Puntos: 0
como puedo generar una tabla cruzada???

Saludos a todos.!

Me encuetro en un problema al generar un reporte con 2 tablas:
personal_catorcenald: sus campos son: id, Personal.
la otra tabla es mov_diario y sus campos son: id_diario, Fecha, Finca, No_Planilla, Nombres, Valor_dia
y la relacion es que una persona puede tener muchos movimientos.
para el caso: en la aplicacion el usuario define el rango de fecha, finca y planilla, para poder generar el reporte.
Detalle del Reporte:
Necesito poner como encabezado horizontalmente las fechas en que hayan trabajado y colocar cada dia segun la fecha lo que gano ese dia (Valor_dia);

| id |Personal | fecha1 | fecha n| fecha n|........... | total |
| 1 | Fulano | 4.20 | 10.89 | 24.25 |...................|(sumatoria de fulano)|

El problema es que como podría ser solo unos cuantos dias como pueda que sea todo el mes.


el query que tengo para las fechas es el siguiente:
SELECT DISTINCT(Fecha) from mov_diario WHERE Fecha >= "2012-11-01" and Fecha <= "2012-11-14" and Finca = " 1" and No_Planilla = "12MD21"

el query para llenar la tabla es el siguiente.:
SELECT personal_catorcenald.Personal, personal_catorcenald.id, Fecha, Finca, Valor_dia
FROM mov_diario, personal_catorcenald
where Fecha >= "2012-11-01" and Fecha <= "2012-11-15" and Finca = " 1" and mov_diario.Nombres = personal_catorcenald.id
GROUP BY id, Fecha
ORDER BY id


y el problema es que se me repite el nombre.. por cada dia trabajado.


****lo he trabajado de esta forma ya que es la forma en como lo lleno en PHP.
ajunto codigo:
Código PHP:
<?php  

include "conexionBD.php";  
//digamos que estos son las fechas introducidas por el usuario.
$fecha1 "2012-11-01";
$fecha2 "2012-11-20"
$finca " 1";
$planilla "12MD21";
//aca tomo la fecha para ponerla de encabezado
$conf=mysql_query("SELECT DISTINCT(Fecha) as Fecha from mov_diario WHERE Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' order by Fecha asc"$conexion);

echo 
"<table width=\"100%\" border=\"1\" align=\"center\">";
echo 
"<tr>";
echo 
"<td>ID</td>";
echo 
"<td>Nombres</td>";

 while(
$rowf mysql_fetch_array($conf)) {  
      
$farray[] = $rowf[Fecha];
      echo 
"<td>$rowf[Fecha]</td>";
    }
echo 
"<td> Dia</td>";
echo 
"</tr>";

$con=mysql_query("SELECT personal_catorcenald.Personal, personal_catorcenald.id,  Fecha, Finca, Valor_dia FROM mov_diario, personal_catorcenald where Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' and mov_diario.Nombres = personal_catorcenald.id  GROUP BY id, Fecha ORDER BY id"$conexion);
    while(
$row mysql_fetch_array($con)) {
    
$dia=$row[Fecha];
    echo 
"<tr>";
    echo 
"<td>$row[id]</td>";
    echo 
"<td>$row[Personal]</td>";
    

        
$col = -1;
            for(
$i 0$i count($farray); $i++){
            
$col++;
                if(
$farray[$i] == $dia){
                    for(
$f=0$f<=$col$f++){
                        if(
$f==$col){
                        echo 
"<td style=background-color:#F5D0A9;>$row[Valor_dia]</td>"// aca se coloca el valor.
                        
}
                    
                    }
                    
                }else{    
                    echo 
"<td>0</td>";
                }
            }
     }
                                    
echo 
"</tr>";
echo 
"<table>";    
        
?>
de esta forma es lo mas cerca que he llegado... Por favor su ayuda...
como puedo simplificarlo...
????????
  #2 (permalink)  
Antiguo 21/11/2012, 02:45
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: como puedo generar una tabla cruzada???

No se puede solucionar con Mysql pero puedes solucionarlo con php.

gnzsoloyo disculpa por saltarme las reglas del subforo, pensaba que estaba en php, podes trasladarlo.

(O dar una solución Mysql)

Igual que usas un condicional para elegir la columna donde pones los datos debes usar un condicional para pasar de linea o no si ha cambiado el nombre....

Algo asi

Código PHP:
Ver original
  1. $idInicial=0;
  2.     while($row = mysql_fetch_array($con)) {
  3.     $dia=$row[Fecha];
  4.     if($idInicial!=$row[id]){
  5.           if($idInicial!=0) echo "</tr>"; //Cierra la linea anterior
  6.           echo "<tr>";
  7.           echo "<td>$row[id]</td>";
  8.           echo "<td>$row[Personal]</td>";
  9.           $idInicial=$row[id];
  10.     }//Abre la linea y pone el nombre del nuevo mobre


Si haces esto tendrás una sola linea por nombre, con lo que deberia cambiar la logica de colocar celdas con 0 cero en las fechas distintas a $dia.

Debes calcular el numero de columnas que deben rellenarse con cero entre fecha y fecha de un nombre.

quizas con solo reiniciar $col a -1 cuando ha cambiado el nombre lo tienes solucionado...

Código PHP:
Ver original
  1. $idInicial=0;
  2.     while($row = mysql_fetch_array($con)) {
  3.     $dia=$row[Fecha];
  4.     if($idInicial!=$row[id]){
  5.           if($idInicial!=0) echo "</tr>"; //Cierra la linea anterior
  6.           echo "<tr>";
  7.           echo "<td>$row[id]</td>";
  8.           echo "<td>$row[Personal]</td>";
  9.           $idInicial=$row[id];
  10.           $col=-1; //Si no ha cambiado el nombre $col sigue con el ultimo valor.?????
  11.           $j=0; //para controlar el for de las fechas Si no ha cambiado el nombre $j sigue con el ultimo valor.
  12.     }//Abre la linea y pone el nombre del nuevo mobre
  13. for($i = $j; $i < count($farray); $i++){
  14.             $col++;
  15.             $j++;
  16.                 if($farray[$i] == $dia){
  17.                     for($f=0; $f<=$col; $f++){
  18.                         if($f==$col){
  19.                         echo "<td style=background-color:#F5D0A9;>$row[Valor_dia]</td>"; // aca se coloca el valor.
  20.                         }
  21.                    
  22.                     }
  23.                    
  24.                 }else{    
  25.                     echo "<td>0</td>";
  26.                 }
  27.             }
  28.      }
  29.                                    
  30. echo "</tr>";
  31. echo "<table>";

Siempre que los datos lleguen ordenados por nombre y fecha funcionará, creo.

Dime si te ha funcionado, lo he hecho al vuelo sin probar nada.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.

Última edición por quimfv; 21/11/2012 a las 03:05
  #3 (permalink)  
Antiguo 21/11/2012, 10:01
 
Fecha de Ingreso: octubre-2012
Ubicación: El Salvador
Mensajes: 14
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: como puedo generar una tabla cruzada???

Mil gracias por tu ayuda..
ahora si puedo hacer que me muestre un solo nombre.
Y continuo con el problema de no poder colocar el salario del dia que haya trabajado.
con tu aporte he vuelto al punto que solo me toma un solo valor y luego los demas espacios los rellena con ceros.
(Ej: estos son los dias que han trabajado en la Finca 1)
acá con nombres repetidos:
ID Nombres 2012-11-01 2012-11-02 2012-11-04 2012-11-05 2012-11-08 2012-11-09 Dia
1 JUAN ARMIDIO LOPEZ 10.46 0 0 0 0 0
1 JUAN ARMIDIO LOPEZ 0 20.55 0 0 0 0
1 JUAN ARMIDIO LOPEZ 0 0 5.96 0 0 0
2 PEDRO PERAZA 5.46 0 0 0 0 0
2 PEDRO PERAZA 0 0 5.96 0 0 0
2 PEDRO PERAZA 0 0 0 5.58 0 0
3 JUAN JOSE BERMUDEZ 5.96 0 0 0 0 0
3 JUAN JOSE BERMUDEZ 0 0 0 5.58 0 0
4 JORGE ANTONIO PEREZ 5.96 0 0 0 0 0
4 JORGE ANTONIO PEREZ 0 0 0 0 0 5.46
etc.


y esta es forma en como queda con un solo nombre:

ID Nombres 2012-11-01 2012-11-02 2012-11-04 2012-11-05 2012-11-08 2012-11-09 Dia
1 JUAN ARMIDIO LOPEZ 10.46 0 0 0 0 0
2 PEDRO PERAZA 5.46 0 0 0 0 0
3 JUAN JOSE BERMUDEZ 5.96 0 0 0 0 0
4 JORGE ANTONIO PEREZ 5.96 0 0 0 0 0
5 GUSTAVO RODRIGUEZ 5.96 0 0 0 0 0

Acá solo me toma el primer valor que tenga el trabajador en la la primer fecha de las seleccionadas y lo coloca en la posicion que debe ser.. pero las otras fechas las deja con 0
espero darme a entender.!
  #4 (permalink)  
Antiguo 21/11/2012, 14:15
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: como puedo generar una tabla cruzada???

Código PHP:
Ver original
  1. <?php  
  2.  
  3. include "conexionBD.php";  
  4. //digamos que estos son las fechas introducidas por el usuario.
  5. $fecha1 = "2012-11-01";
  6. $fecha2 = "2012-11-20";
  7. $finca = " 1";
  8. $planilla = "12MD21";
  9. //aca tomo la fecha para ponerla de encabezado
  10. $conf=mysql_query("SELECT DISTINCT(Fecha) as Fecha from mov_diario WHERE Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' order by Fecha asc", $conexion);
  11.  
  12. echo "<table width=\"100%\" border=\"1\" align=\"center\">";
  13. echo "<tr>";
  14. echo "<td>ID</td>";
  15. echo "<td>Nombres</td>";
  16.  
  17.  while($rowf = mysql_fetch_array($conf)) {  
  18.       $farray[] = $rowf['Fecha'];
  19.       echo "<td>".$rowf['Fecha']."</td>";
  20.     }
  21. //echo "<td> Dia</td>";
  22. echo "</tr>";
  23.  
  24. $con=mysql_query("SELECT personal_catorcenald.Personal, personal_catorcenald.id,  Fecha, Finca, Valor_dia FROM mov_diario, personal_catorcenald where Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' and mov_diario.Nombres = personal_catorcenald.id  GROUP BY id, Fecha ORDER BY id", $conexion);
  25. $idInicial=0;
  26.  
  27.     while($row = mysql_fetch_array($con)) {
  28.     $dia=$row['Fecha'];
  29.    
  30.      if($idInicial!=$row[id]){
  31.          if ($idInicial != 0) {
  32.             for ($f = $col; $f < count($farray); $f++) {
  33.                 echo "<td>0</td>";
  34.             }
  35.             echo "</tr>";
  36.         }//Cierra la linea anterior
  37.           echo "<tr>";
  38.           echo "<td>".$row['id']."</td>";
  39.           echo "<td>".$row['Personal']."</td>";
  40.           $idInicial=$row['id'];
  41.       $col = 0; //Si no ha cambiado el nombre $col sigue con el ultimo valor.
  42.     } //Abre la linea y pone el nombre del nuevo mobre
  43.  
  44.     for ($i = $col; $i < count($farray); $i++) {
  45.         $col++;
  46.         if ($farray[$i] == $dia) {
  47.             echo "<td style=background-color:#F5D0A9;>" . $row['Valor_dia'] . "</td>"; // aca se coloca el valor.
  48.             break;
  49.         } else {
  50.             echo "<td>0</td>";
  51.         }
  52.     }
  53. }
  54.  
  55. echo "</tr>";
  56. echo "<table>";
  57. ?>

Ahora....creo. Di si ha funcionado.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #5 (permalink)  
Antiguo 21/11/2012, 14:34
 
Fecha de Ingreso: octubre-2012
Ubicación: El Salvador
Mensajes: 14
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: como puedo generar una tabla cruzada???

Cita:
Ahora....creo. Di si ha funcionado.
Maestro.!!!!!

HA FUNCIONADO.!!!!

Muchas gracias... me has ayudado en grande manera.!!!

mister.. hasta donde le envio la soda.???????!
bendiciones.!

Última edición por Chevy1975; 21/11/2012 a las 14:34 Razón: correccion
  #6 (permalink)  
Antiguo 24/11/2012, 00:39
 
Fecha de Ingreso: octubre-2012
Ubicación: El Salvador
Mensajes: 14
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: como puedo generar una tabla cruzada???

Cita:
Iniciado por quimfv Ver Mensaje
Ahora....creo. Di si ha funcionado.
Saludos nuevamente..

Tengo otra consulta referente al codigo que en el que me ayudaste..
y es como hacer un corte de control para sacar subtotales y totales.

He estado leyendo hacerca del tema pero no he logrado poder aplicarlo alcodigo..

Es decir: un total por fila Ej:
Nombre|fechas...........| Total Trabajador
Fulano 10+10+10+5.50 35.5
y abajo el total de cada día.
Total de cada columna.
y por ultimo la sumatoria de todo. Como total Global.

Alguna idea de como podría hacer eso..????

de antemano Mil Gracias.!
  #7 (permalink)  
Antiguo 26/11/2012, 02:30
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Sabadell
Mensajes: 4.897
Antigüedad: 16 años, 1 mes
Puntos: 574
Respuesta: como puedo generar una tabla cruzada???

Igual que distingues en que columna debes poner el valor es facil sumar ese valor a una variable que represente a la columna

$arrayTotales=new Array();

los elementos de ese array serian las columnas y en ellos puedes sumar los valores para al final tener el total.

En cuanto al total de fila, aun más facil, si eres capaz de distinguir entre los nombres es cuestion de ir sumando en una variable y poner el resultado en la ultima columna.

$totalLinea=0;

sumar mientras no cambia el id, mostrar el resultado y resetearla al iniciar un nuevo nombre o id.
__________________
Quim
--------------------------------------------------
Ayudar a ayudar es una buena práctica!!! Y da buenos resultados.
  #8 (permalink)  
Antiguo 26/11/2012, 03:12
 
Fecha de Ingreso: octubre-2012
Ubicación: El Salvador
Mensajes: 14
Antigüedad: 11 años, 6 meses
Puntos: 0
Respuesta: como puedo generar una tabla cruzada???

saludos... nuevamente..


Agradecido por su contetacion
He estado probando el codigo y se me han presentado varios inconvenientes
estoy haciendo consultas en este caso a otra tabla..
y el problema se me presenta a la hora de generar el total por fila ya que no todos los suma correctamente.. por que la casilla de resultado se intercala en el llenado.
en vez de quedar a la derecha.
aca está el codigo.:
Código PHP:
    $conf=mysql_query("SELECT personal_catorcenal.Nombres, personal_catorcenal.id,  Fecha, Finca, Round(Produccion, 1) as prod, Cuadrilla FROM mov_obra, personal_catorcenal where Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' and mov_obra.Nombres = personal_catorcenal.id and Cuadrilla = '$cuad' GROUP BY Fecha ORDER BY Fecha"$conexion);
    echo 
"<table width=\"90%\" border=\"1\" align=\"left\">"// tabla hijo
    
echo "<tr>";
    echo 
"<td align=\"Center\">ID</td>";
    echo 
"<td align=\"Center\">Nombres</td>";
     while(
$rowf mysql_fetch_array($conf)) {  
          
$farray[] = $rowf['Fecha'];
               echo 
"<td align=\"center\">$rowf[Fecha]</td>";
     }
    echo 
"<td align=\"Center\">Produccion</td>";
    echo 
"</tr>";
    
$con=mysql_query("SELECT personal_catorcenal.Nombres, personal_catorcenal.id,  Fecha, Finca, Round(Produccion, 1) as prod, Round(SUM(Valor_dia), 2) as Valor, Cuadrilla FROM mov_obra, personal_catorcenal where Fecha >= '$fecha1' and Fecha <= '$fecha2' and Finca = '$finca' and mov_obra.Nombres = personal_catorcenal.id and Cuadrilla = '$cuad' GROUP BY personal_catorcenal.Nombres, Fecha ORDER BY id"$conexion);
    
$idInicial=0;
      while(
$row mysql_fetch_array($con)) {
        
$dia=$row['Fecha'];
        if(
$idInicial!=$row[id]){
              if (
$idInicial != 0) {
                for (
$f $col$f count($farray); $f++) {
                   echo 
"<td>0</td>";
                }
            }
//Cierra la linea anterior
              
echo "<tr>";
              echo 
"<td align=\"center\">$row[id]</td>";
              echo 
"<td align=\"left\">$row[Nombres]</td>";
              
$idInicial=$row['id'];
          
$col 0//Si no ha cambiado el nombre $col sigue con el ultimo valor.
          
$cols 0;
       } 
//Abre la linea y pone el nombre del nuevo mobre
        ////*********************  LLENADO DE LA tabla*************************************** /////
        
$suma +=$row['prod'];
                      for (
$i $col$i count($farray); $i++) {//for
                     
$col++;
                       if (
$farray[$i] == $dia) { //if
                    
echo "<td align=\"center\" style=background-color:#FFDD44;>$row[prod]</td>"// aca se coloca el valor.
                           
break;
                        }else { 
//else
                        
echo "<td>0</td>";
                        }
//else
                        
// for de llenado.

         
for ($j $cols$j <= count($farray); $j++){
           
//$cols ++;
            
if ($farray[$j] == $dia){
                echo 
"<td align=\"center\" style=background-color:#66AAAA;>$suma</td>";
                }
//echo "<tr>";
                
}//for
        ///////////////********** FIN DE LLENADO DE la tabla *********** ///////////
            
        
            
            
}//final de while
            
echo "<tr>";
            echo 
"<td align=\"center\" style=background-color:#99FFFF;>Total general</td>";
            echo 
"<td align=\"center\" style=background-color:#66AAAA;>$suma</td>";
            
//}
        
    ////************************* 

    
echo "</tr>";
    echo 
"</table>"
?> 
skype: Lnrdrvs

Etiquetas: select, sql, tabla, campos
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:59.