phparraysrowmultiple-columnstranspose

Dynamic column amount from rows in PHP


I have a dataset from which i want to display the unique values in a row from 1 column as columns, and the first column from unique sets from an other row. And then fill the matrix with the values from a third row with corresponding values from the displayed column-row combination. But then also display in the second column the values of a second dataset which also correspond with the first column as displayed.

I did use the search on this Stackoverflow for hours now, and i just couldn't find the right connection. I do know i have to build 2 arrays, but i just couldn't figure what i am doing wrong. and didn't even come around to sum and the extra link to the second set. Because the first thing wouldn't work. I am not hung up on the type of solution. any solution or pointer will do by now.

Data:

BLOEMEN table:
bloem_id bloem_naam
1120 Petra's Wedding
1145 White Aster
1225 My Love
1305 Caramel Antique
1315 Eveline
1330 Polar Ice
1340 Snow Cap  
1391 Snow Cap Deco
etc

knollen table:
bloem_id jaar teler_id plant_aant
1145 2023 Tjakan 400
1340 2023 Excellent 450
1340 2023 Fatal 5500
etc

Wanted output (arbitrary, not counts per cell not based on input): The number of columns should be based on number of 'telers' that filled the amounts.

So can differ per year that they plant their flowers.

Bloemsoort Klein cuba Tjakan Etc
1120 White aster 100
1145 My love 140 250
Total 140 350
<?php
include 'verbinding.php';
$jaar = date("Y");
$conn = new mysqli($host, $username, $password, $database); 
$SQL = "SELECT knollen.bloem_id, knollen.jaar, knollen.plant_aant, BLOEMEN.bloem_naam, knollen.teler_id       AS teler_id
                FROM knollen 
                INNER JOIN BLOEMEN
                ON knollen.bloem_id = BLOEMEN.bloem_id
                WHERE jaar = $jaar-1
                ORDER BY bloem_id";
     
$grouped = [];
$columns = [];    
       
$resultObject = $result = mysqli_query($conn, $SQL);
foreach ($resultObject as $row) {
    $grouped[$row['bloem_id']] = $row['plant_aant'];
    $columns[$row['teler_id']] = $row['teler_id'];
}
       
sort($columns);
$defaults = array_fill_keys($columns,'-');
array_unshift($columns, 'teler_id');
      
?>
 
    <table id="example" class="display" style="width:100%" align="center">
    <thead>
  
<?php
 
        while($result = mysqli_fetch_array($resultObject))
        {
            echo "<tr>
         <td>title 1</td> 
         <td>title 2</td>
         </tr>";
        }
?>
    </thead>
 
    <tbody>
 
<?php
 
        while($result = mysqli_fetch_array($resultObject))
        {
            echo "<tr>
         <td colspan='2'> ".$row['bloem_id']." </td>
         <td> ".$row['plant_aant']." </td> 
         
          </tr>";
        }
 
?>

Solution

  • Best solution I can think of is to loop over the database result and restructure it for easier printing in the table. This will also allow you to calculate the totals for the bottom row.

    $grouped = [];
    $bloemen = [];
    $telers = [];
    
    $resultObject = mysqli_query($conn, $SQL);
    foreach ($resultObject as $row) {
        $grouped[$row['bloem_id']][$row['teler_id']] = $row['plant_aant'];
        $bloemen[$row['bloem_id']] = $row['bloem_naam'];
        if (isset($telers[$row['teler_id']])) {
            $telers[$row['teler_id']] += $row['plant_aant'];
        } else {
            $telers[$row['teler_id']] = $row['plant_aant'];
        }
    }
    
    ksort($telers);
    

    $grouped now contains the number of plants for available 'bloem' + 'teler' combinations. $bloemen contains an array of key value pairs bloem_id => bloem_naam for display in the first 2 columns. $telers contains an array of key value pairs teler_id => total for display in the top and bottom row.

    You only need to ksort (sort by array key) $telers, $bloemen is already sorted because of the ORDER BY in your query.

    Now build the table:

    <table id="example" class="display" style="width:100%" align="center">
        <thead>
            <tr>
                <th></th>
                <th>Bloemsoort</th>
                <?php
                    foreach ($telers as $teler_id => $total) {
                        echo "<th>{$teler_id}</th>";
                    }
                ?>
            </tr>
        </thead>
        <tbody>
            <?php
                foreach ($bloemen as $bloem_id => $bloem_naam) {
                    echo "<tr><td>{$bloem_id}</td><td>{$bloem_naam}</td>";
                    foreach ($telers as $teler_id => $total) {
                        echo "<td>";
                        if (isset($grouped[$bloem_id][$teler_id])) {
                            echo $grouped[$bloem_id][$teler_id];
                        }
                        echo "</td>";
                    }
                    echo "</tr>";
                }
            ?>
            <tr>
                <td></td>
                <td>Total</td>
                <?php
                    foreach ($telers as $total) {
                        echo "<td>{$total}</td>";
                    }
                ?>
            </tr>
        </tbody>
    </table>