My apologies if this has been addressed - I have been searching all day and haven't found anything that meets my needs.
I have a foreach loop in php that is repeating information ad nauseum, and I am not sure how to fix it. I have tried grouping, array_unique, etc., and haven't found a solution. No row is a true duplicate of another when all variables are taken into account.
I have a table where each line represents a winning ticket. Each line has a unique ID, a date, a tier (1,2,3), and some other variables worth of information. I would like to organize this by date, ascending by tier number, where the date is listed once and each ticket is listed once. Right now, each row is listed as a ticket, but repeats multiple times. Here is my code - I have removed the displays in between as those work fine:
$selectResults = "SELECT * FROM mytable WHERE YEAR(date) = 2014 ORDER BY date DESC, tier ASC";
$getResults = #mysqli_query($connect, $selectResults) or die('query error: ' . mysqli_error($connect));
if(mysqli_num_rows($getResults) == 0){
echo "There are no tickets to display.";
}else{
echo "<table><tr><th>Date</th><th>Tier</th><th>Points</th><th>Prize Amount</th></tr>";
while($row = mysqli_fetch_array($getResults)){
extract($row);
foreach($row as $ticket => $date){
echo "<tr><td>" . date('n/j/Y', strtotime($date)) . "</td><td> </td><td> </td><td> </td></tr>";
if (1 == $tier)
{
(Display Tier 1 tickets for date)
}
if (2 == $tier)
{
(Display Tier 2 tickets for date)
}
if (3 == $tier)
{
(Display Tier 3 tickets for date)
}
}
echo "<tr class='bottomRow'><td colspan='4' /></tr>";
}
echo "</table>";
Get rid of the foreach loop:
foreach ($row as $ticket => $date)
You're already looping over the rows with the while loop. $row just contains a single row, with each column as an element of the array.
Your code should look like:
$last_date = null;
while ($row = mysqli_fetch_assoc($getResults)) {
extract($row);
if ($date != $last_date {
echo "<tr><td>" . date('n/j/Y', strtotime($date)) . "</td><td> </td><td> </td><td> </td></tr>";
$last_date = $date;
}
// Display ticket details
}
Related
Hello Fellow Stack Users, I have an issue. I am running a booking system and I'm in the process on changing some of the code to ajax so that the user does not have to be redirected. My database has colums. one date and the other one time. the code querys the database and gets one result for each date. december 1, december 2 etc and doesn't show the times. The issue i am having is that i can not run code which i can click the date and it will query the database to find all the time slots associated with that date.
some code below
index.php
$sql = "SELECT DISTINCT day, hour FROM availability WHERE booked='' and day >= CURDATE()";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$next = date("M jS ", strtotime("".$row["day"] .""));
echo "<a class='button' style='margin:10px;' href=fetch.php?pageid=" . $row["day"] . "> <p style='font-size:20px; margin:0px;'>$next</p> ". $row["hour"]. "</a>";
}
} else {
echo "You are booked up for the week";
}
$conn->close();
fetch.php
$sql = "SELECT DISTINCT day FROM availability WHERE booked='' and day >= CURDATE()";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "<a class='button' style='margin:10px;' href=book_process.php?pageid=" . $row["id"] . "> <p style='font-size:20px; margin:0px;'>$next</p> ". $row["hour"]. "</a>";
}
} else {
echo "You are booked up for the week";
}
$conn->close();
in fetch you should click a time and then it should update the row in the process page i have not included. I am not very fluent coding ajax but i thought that now is the time to learn.
I have “ordered by” a database to be in ascending country order, then descending years. Each database record contains: countryname, year, details. There are many duplicate countries, but the years are different. For instance:
Albania, 2000, details
Albania, 1965, details
Croatia, 2014, details
Croatia, 2003, details
Can’t figure out how to echo the array to get results like the following where country is on one line and years & details are listed below without duplicating the name of the country:
Albania
2000, details
1965, details
Croatia
2014, details
2003, details
Seems like I need foreach distinct country, echo year and details?
Here is my php so far:
$result = mysql_query("SELECT country, year, details FROM studies ORDER BY country, year DESC ");
//output data from each row in db
while($row = mysql_fetch_array($result)) {
echo " Country: " .$row['country']. "<br /> Year: " .$row['year']. " Details: ".$row['details']. "<br /><br /> ";
}
Would appreciate any help, I'm stumped!
Try adding a country check:
$newcountry = '';
while($row = mysql_fetch_array($result)) {
if ($newcountry != $row['country']) {
echo "Country:". $row['country']."<br />";
$newcountry = $row['country'];
}
echo " Year: " .$row['year']. " Details: ".$row['details']. "<br /><br /> ";
}
This should work, because you have ordered your query by Country. This is critical, otherwise you should absolutely add a GROUP BY clause to your SQL.
EDIT: to add a <div> around the group, you simply would change the echo sequence, checking first to see if the country has already been set once. It would look like:
$newcountry = 'undefined';
while($row = mysql_fetch_array($result)) {
if ($newcountry !='undefined' && $newcountry != $row['country']){
echo '</div>'; // only add a closing div if a new country (and not 1st)
}
if ($newcountry != $row['country']) {
echo "Country:". $row['country']."<br /><div class='countryDetail'>";
$newcountry = $row['country'];
}// added the start of the <div>
echo " Year: " .$row['year']. " Details: ".$row['details']. "<br /><br /> ";
}
if ($newcountry != 'undefined') { //make sure at least one <div> is set
echo "</div>"; // close the last <div>
}
I added the class countryDetail to the div, so you can use this with toggle in your jQuery.
You can use nested while loops. You might also want to use PDO/mysqli_ functions/prepared statements in place of mysql_ functions:
// get unique country list first
$sql1 = "SELECT DISTINCT(country) FROM studies ORDER BY country";
$result1 = mysql_query($sql1);
// iterate through result set of sql1
while($row1 = mysql_fetch_array($result1))
{
$country = $row1['country'];
echo "<br>"; // new line
echo $country;
// get year, details for each country
$sql2 = "SELECT year, details FROM studies WHERE country = '$country' ORDER BY year DESC";
$result2 = mysql_query($sql2);
// iterate through result set of $sql2
while ($row2 = mysql_fetch_array($result2))
{
echo "<br>"; // new line
echo $row2['year']. ", " . $row2['details'];
}
}
loop party!
$rows = [];
while($row = mysql_fetch_array($result)) {
$rows[ $row['country'] ] = [ $row['year'], $row['details'] ];
}
foreach($rows as $country => $row) {
$details = array_map(function($items) { return sprintf("\t - %s: %s\n", $items[0], $items[1]) }, $row);
echo sprintf("\n%s:\n %s", $country, $details);
}
I want to print data from the database in a horizontal manner.
I have two table one that holds products names and another that holds products performance by months eg i want data to appear in a table like this
product name,performance by months from january to december
eg
product A,1000 ,2000, etc performance by months
product B,2000,3300, etc performace by months
Edit: I didn't realize you said you have two tables. So the query in my solution should be adapted with a JOIN and ordered, but we cannot dig further into this without knowing your schema. My solution addresses the main concern (i.e. printing results horizontally), provided you obtain two fields to show in two different rows.
Just retrieve your data and store it in a multidimensional array, THEN create the table.
$data = array();
$sql = "SELECT product, performance FROM table";
$rs = mysql_query($sql);
while ($row = mysql_fetch_assoc($rs))
{
$data[] = array($row['product'], $row['performance']);
}
echo "<table><tr>";
// print products in the first line of the table
foreach($data as $d)
{
echo "<td>" . $d[0] . "</td>";
}
echo "</tr><tr>";
// then print performances
foreach($data as $d)
{
echo "<td>" . $d[1] . "</td>";
}
echo "</tr></table>";
This is for a timetable and what it does is displays the previous day's timetable and who has booked each slot (this is for a radio station.)
At the moment it displays who has booked each slot in chronological order however I would like it to say the time next to each result. The query outputs 24 rows (which is from Midnight to 23:00) and next to each slot I would like it to say (00:00, 01:00, 02:00, 03:00... 21:00, 22:00 so on so forth.)
This is my current code:
<?php
include("../config.php");
#// Timetable Clearup Variabls
$yesterday = strtotime('yesterday');
$yesterdow = date('l',$yesterday);
echo "<table width=\"580px\" class=\"board\" border=\>";
$order = "SELECT * FROM timetable WHERE day = '$yesterdow'";
$result = mysql_query($order);
// Error checking
if (!$result) {
// output error, take other action
}
else {
while ($row=mysql_fetch_array($result)){
// Append all results onto an array
$rowset[] = $row;
}
}
foreach ($rowset as $row) {
echo "<tr><td>" . htmlspecialchars($row['username']) . "</td></tr>";
}
?>
Can you help?
I think we're all looking too hard at a VERY simple problem. You are already using SELECT * in your query, so you're already fetching all three columns from your table. So now, all you need to do is add another cell to each row of your table.
echo "<tr><td>" . htmlspecialchars($row['username']) . "</td><td>" . htmlspecialchars($row['time']) . "</td></tr>";
And to make sure you are fetching your rows in the correct order, you should add an ORDER BY to your query:
SELECT * FROM timetable WHERE day = '$yesterdow' ORDER BY time
If you don't specify an ORDER BY clause, you have no guarantee that you will get the results in any particular order.
And one last thing, you are looping through the rows twice, unnecessarily. Get rid of the foreach loop and put the echo directly inside the while loop.
try this:
foreach ($rowset as $row) {
echo "<tr><td>" . htmlspecialchars($row['username']) . htmlspecialchars($row['time'])"</td></tr>";
The code belows gives me only 18 records
<?php
$result4 = mysql_query("select Distinct Country from trendsmtable where WHORegionAC='Europe - all countries' GROUP BY Country ");
echo "<table width=880 align=center>";
echo "<tr><td colspan=4 style='font-family:Arial;'><b>European Region</b></td></tr>";
$num_columns4 = 4;
$num_rows4 = mysql_num_rows($result4);
$i=0;
while($row4 = mysql_fetch_assoc($result4)){
$results[$i] = $row4['Country'];
$i++;
}
unset($i);
$k=0;
for ($i=0;$i<=($num_rows4/($num_columns4+1));$i++){
echo '<tr>';
for($j=1;$j<=$num_columns4;$j++){
echo "<td width=220 style='font-family:Arial; font-size:12px'>".$results[$k].'</td>';
$k++;
}
echo '</tr>';
$k++;
}
echo "</table>";
?>
while the select statement
select Distinct Country from trendsmtable where WHORegionAC='Europe -
all countries'
returns 22 rows while I execute it in mysql which is correct!
Please help me to found the error.
Well, you have an extra $k++ in there that you don't need:
$k++; // keep this one
}
echo '</tr>';
$k++; // remove this one
}
Edit
I've gone through your code and I've made some edits. Hopefully they'll clean your issue along the way:
// got rid of group by. With a select distinct, it isn't necessary
$result4 = mysql_query("select Distinct Country from trendsmtable where ".
"WHORegionAC='Europe - all countries'");
// a good practice is to always double-quote your HTML attributes.
echo "<table width=\"880\" align=\"center\">";
echo "<tr><td colspan=4 style=\"font-family:Arial;\">".
"<b>European Region</b></td></tr>";
$num_columns4 = 4; // where does 4 come from.
// $results was never initialized before.
$results = array();
while($row4 = mysql_fetch_assoc($result4)){
// This is generally thought of as "cleaner" than using an index.
// And since there cannot be more than, say, 220 rows, cleanliness
// should be a high-priority standard.
$results[] = $row4['Country'];
}
// mysql_num_rows rarely provides any major benefit at all.
$num_rows4 = count($results);
foreach( $results as $key => $val )
{
// This happens every time we fill all columns and need a new row.
if( !( $key % $num_columns4 ) )
{
// makes it so that after the first time this closes the prev
// row before starting a new one.
if( $key ) echo '</tr>';
echo '<tr>';
}
// insert nag about CSS
echo '<td width="220" style="font-family:Arial; font-size:12px">'.
$val.
'</td>';
}
echo '</tr></table>';
I think the PHP looks a little odd, it looks like you are looping from 0 to (22 / 5)
then in the inner loop 4 times.
The group by should not make any difference as you are doing a select distinct
Your SQL code in the PHP file contains a GROUP BY clause, which can reduce the number of rows returned, if you have a country more than once in the db.