Habrá muchas maneras de hacer esto; algunas técnicas involucran sql para preparar el pivote dinámico. Mi fragmento a continuación usará php para realizar el pivote.
- Recorra el objeto del conjunto de resultados con un
foreach()
-- no, no necesita llamar a una función de recuperación para acceder a los datos porque el objeto de resultado es iterable. - Cree una matriz de agrupación multidimensional con nombres como claves de primer nivel, luego subarreglos con años como claves y valores como valores.
- Cree una serie de años únicos. Mi enfoque garantizará la unicidad al asignar el año como clave y valor, ya que las matrices no pueden contener claves duplicadas, los valores serán únicos sin tener que llamar a
array_unique()
más tarde. - Ordenar los años ASC
- Cree una matriz de valores predeterminados para cada año. En este caso, estoy asignando
-
como valor predeterminado. - Agregue la palabra literal
name
al frente de la matriz que contiene años únicos; esto se usará para completar la fila de encabezado de la tabla. - Prefiero usar
implode()
para crear una fila de tabla de celdas variables. printf()
es una forma limpia de combinar texto literal con variables:evita la sintaxis de interpolación/concatenación.- En cada fila subsiguiente de la tabla, reemplace los valores anuales predeterminados con los valores anuales de la persona relativa y presente con
implode()
. - Si existe alguna posibilidad de que el conjunto de resultados esté vacío, es posible que desee envolver la mayor parte de este fragmento en un
if ($resultObject) { ... }
bloque.
Código:(Demostración )
$grouped = [];
$columns = [];
$resultObject = $mysqli->query("SELECT `name`, `value`, `year` FROM `Testab`");
foreach ($resultObject as $row) {
$grouped[$row['name']][$row['year']] = $row['value'];
$columns[$row['year']] = $row['year'];
}
sort($columns);
$defaults = array_fill_keys($columns, '-');
array_unshift($columns, 'name');
echo "<table>";
printf(
'<tr><th>%s</th></tr>',
implode('</th><th>', $columns)
);
foreach ($grouped as $name => $records) {
printf(
'<tr><td>%s</td><td>%s</td></tr>',
$name,
implode('</td><td>', array_replace($defaults, $records))
);
}
echo "</table>";
Salida:(con espaciado/tabulación añadidos para facilitar la lectura)
<table>
<tr>
<th>name</th> <th>2018</th> <th>2019</th> <th>2020</th>
</tr>
<tr>
<td>Tom</td> <td>15</td> <td>4</td> <td>6</td>
</tr>
<tr>
<td>Kate</td> <td>18</td> <td>20</td> <td>-</td>
</tr>
</table>