I have data coming back from a query. It could be a join or just a simple table selecting everything. I would like the data to be presented in descending order of date. And
<?php
// MYSQLI_REPORT_ALL remmed out to avoid
//Fatal error: Uncaught exception 'mysqli_sql_exception' with message 'No index used in query/prepared statement'
// which is certainly the case with the demo query
//mysqli_report(MYSQLI_REPORT_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // so go with this one
error_reporting(E_ALL); // report all PHP errors
ini_set("display_errors", 1);
//echo "start<br/>";
try {
$mysqli= new mysqli('hostname', 'dbuser', 'password', 'dbname');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') '
. $mysqli->connect_error);
}
// your query can be a join. No difference. Just plug yours in and tweak everywhere as necessary
$query = "select ayr,otherStuff from myTable123 order by ayr desc";
// The following variable is used to pick up a "year change" while processing the data to segment tables
$curYear="^^junk^^"; // so set it to junk first, so first time in is a change
$bOneYet=false; // has there been any output at all yet. I mean anything? So far, no
if(!$result = $mysqli->query($query)){
die('There was an error running the query [' . $mysqli->error . ']');
}
while ($row = $result->fetch_assoc()) {
if ($row['ayr']!=$curYear) {
// the year has changed (including the first time in this while)
if (!$bOneYet) {
$bOneYet=true; // will one get in here once
}
else {
// must end previous table
echo "</table><p><p>";
}
// regardless, we need a new table
echo "<table border=1><tr><th>The Year</th><th>The other thing</th></tr>";
}
echo "<tr><td>" . $row['ayr'] . "</td><td>" . $row['otherStuff'] . "</td></tr>";
$curYear=$row['ayr']; // kind of important. Facilitates subsequent year table segments
}
echo "</table><p>"; // close up the last dangling table
$result->free();
$mysqli->close();
}
catch (mysqli_sql_exception $e) {
throw $e;
}
Hopefully the source code comments are sufficient in-line to describe the way the years are segmented by tables. Focus on variable $curYear
which picks up that change as the data is processed, descending, by year.
The variable $bOneYet
is false only one time through the loop. The rational is that when a year change occurs, </table>
is written out, except for the first time through.
Don't forget the importance of error reporting as seen at the top of the code. And steer toward mysqli
or pdo
.
Display errors for test and staging, never production.
I didn't like the way the other answer generated the tables from the database values so I decided to write a new answer.
One thing I always recommend doing is putting the code to retrieve the data from the database in a function so it's easily usable in multiple places.
Another thing that I would like to recommend is to use the HTML more like a template instead of echoing the entire table.
The rest of the specific information is in the comments in the code.
<?php
function getData() {
$mysqli= new mysqli('localhost', 'root', '', 'test');
if ($mysqli->connect_error) {
die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}
$query = "select id, ayr, otherStuff from myTable123 order by ayr desc";
if(!$result = $mysqli->query($query)){
die('There was an error running the query [' . $mysqli->error . ']');
}
$data = array();
while ($row = $result->fetch_assoc()) {
//Use the "$row['ayr']" value here to group by year. The "$row['id']" is optional but recommended as it is always unique and handy to have in some cases.
$data[$row['ayr']][$row['id']] = array(
"id" => $row['id'],
"ayr" => $row['ayr'],
"otherstuff" => $row['otherStuff'],
);
}
$result->free();
$mysqli->close();
return $data;
}
//The data returned by getData() is already sorted so you only have to loop through it to generate the table.
$data_per_year = getData();
?>
<!--This loop will run for each seperate year in the array-->
<?php foreach($data_per_year as $year => $data) : ?>
<table border="1">
<thead>
<tr>
<th>Year</th>
<th>Other stuff</th>
</tr>
</thead>
<tbody>
<!--This loop will run for each seperate row of data in that specific year-->
<?php foreach ($data as $id_row => $row) : ?>
<tr>
<td><?php echo $row['ayr']; ?></td>
<td><?php echo $row['otherstuff']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endforeach; ?>