Data jsou v databázi obvykle uložena v podobě jednotlivých hodnot. Jak postupovat, když z nich chceme sestavit přehledovou tabulku, která bude mít v jednotlivých řádcích např. datum a ve sloupcích skupinu? Na webu byste možná našli způsob, jak to udělat v prostém SQL, mnohem jednodušší, přehlednější a obvykle i rychlejší bude z databáze získat základní data a do tabulky je sestavit v PHP:
<?php // načtení dat do pole array("datum" => array("skupina" => "data")) $data = array(); $result = mysql_query("SELECT datum, skupina, SUM(cena) AS soucet, COUNT(*) AS pocet FROM tab GROUP BY datum, skupina"); while ($row = mysql_fetch_assoc($result)) { $data[$row["datum"]][$row["skupina"]] = "$row[soucet] ($row[pocet])"; } mysql_free_result($result); // načtení a vypsání všech skupin $skupiny = array(); $result = mysql_query("SELECT id, nazev FROM skupiny"); echo "<thead><tr><th></th>"; while ($row = mysql_fetch_assoc($result)) { echo "<th>" . htmlspecialchars($row["nazev"]) . "</th>"; $skupiny[] = $row["id"]; } echo "</tr></thead>\n"; mysql_free_result($result); // vypsání všech dat foreach ($data as $datum => $row) { echo "<tr><th>$datum</th>"; foreach ($skupiny as $skupina) { echo "<td>$row[$skupina]</td>"; } echo "</tr>\n"; } ?>
Kód nejprve načte všechna data, potom vypíše skupiny a na závěr i data. Počítá se s tím, že pro každé datum nemusí být záznam u každé skupiny. Pokud bychom chtěli zobrazit údaje jen pro skupiny, které v datech mají záznam alespoň u jednoho dne, naplnili bychom pole $skupiny
už při průchodu dat a nechali vypsat názvy jen těchto skupiny: "WHERE id IN (" . implode(", ", array_keys($skupiny)) . ")"
.
Nevýhoda popsaného řešení spočívá v tom, že je náročné na paměť. Pokud by dat bylo hodně, tak výsledky můžeme na výstup posílat postupně:
<?php $datum = ""; $result = mysql_query("SELECT datum, skupina, SUM(cena) AS soucet, COUNT(*) AS pocet FROM tab GROUP BY datum, skupina"); while ($row = mysql_fetch_assoc($result)) { if ($datum != $row["datum"]) { reset($skupiny); echo ($datum ? "</tr>\n" : "") . "<tr><th>$row[datum]</th>"; $datum = $row["datum"]; } while (current($skupiny) != $row["skupina"]) { echo "<td></td>"; next($skupiny); } echo "<td>$row[soucet] ($row[pocet])</td>"; next($skupiny); } echo ($datum ? "</tr>\n" : ""); mysql_free_result($result); ?>
Kód používá funkce pro získání aktuálního prvku pole current, pro přesun na další prvek next a pro přesun interního ukazatele na začátek pole reset. Kód se spoléhá na to, že v datech nebudou odkazy na neexistující skupiny, protože jinak dojde k zacyklení. Mohlo by nám také vadit, že na konci neúplných řádků nejsou vypsané prázdné buňky tabulky (pokud bychom v tom případě třeba chtěli zobrazit nějakou speciální hodnotu nebo v pravém sloupci celkový součet) – to by se dalo vyřešit doprojitím pole skupin ve větvi $datum != $row["datum"]
a po skončení cyklu.
Diskuse je zrušena z důvodu spamu.