I'm trying to display ul>li list using PHP while loop and MYSQL.
My database 'company' has table 'news' with 2 columns ' id & content'.
The while loop works correctly it is returning two 'li' = as there are two rows in the table.
But, instate of data from the table something like this $indx." - ".$ID." ".$CONTENT." is inserted in each 'li'.
My while loop:
$readNews_SQLselect = "SELECT ";
$readNews_SQLselect .= "id, content "; // rows names
$readNews_SQLselect .= "FROM ";
$readNews_SQLselect .= "news "; // table name
$readNews_SQLselect_Query = mysql_query($readNews_SQLselect);
$indx = 1;
while ($row = mysql_fetch_array($readNews_SQLselect_Query, MYSQL_ASSOC)) {
$ID = $row['id'];
$CONTENT = $row['content'];
echo '<li>$indx." - ".$ID." ".$CONTENT."</li>';
$indx++;
}
mysql_free_result($readNews_SQLselect_Query);
I'm 99% sure is the syntax issue with echo '<li>$indx." - ".$ID." ".$CONTENT."</li>';.
PHP doesn't substitute variables in single quoted strings.
echo "<li>$indx - $ID $CONTENT</li>";
replace
'<li>$indx." - ".$ID." ".$CONTENT."</li>';
with:
'<li>'. $indx .' - ' . $ID .' ' . $CONTENT . '</li>';
EDIT 1
or with:
"<li>$indx - $ID $CONTENT</li>";
Related
I have this database table called items.
I am displaying these items with the following code. But I want to display top 5 items ordered by their overall average rating, whilst also displaying the number of reviews the score is based on.
Can anybody please help me with this?
$sql = "SELECT itme_id, name, description, rating, item_type, no_of_reviews FROM itmes";
$items = mysqli_query($con, $sql) or die(mysqli_error());
while($row = mysqli_fetch_array($itmes))
{
$html = "";
if ($row['item_type'] == ITEM_HIDDEN)
{
continue;
}
else
{
$name = $row['name'];
$description = $row['description'];
$rating = $row['rating'];
$html .= "<tr><td>";
$html .= "<h3>" . $name . "</h3>";
$html .= "<p>" . $description . "</p>";
$html .= "<b>Rating: " . $rating . "</b> ";
$html .= "(Reviews: " . $row['no_of_reviews'] . ")";
$html .= "</td></tr>";
}
echo $html;
}
Try putting your query like this:
SELECT item_id, name, description, AVG(`rating`) as `avg_rating`,
item_type, SUM(`no_of_reviews`) as reviews
FROM items
GROUP BY name
LIMIT 5
Hope this helps.
Check the example and results here:
http://sqlfiddle.com/#!9/37b495/2
We have this MySQL query where we want to find the date_time and price_open from price table and update these two values into the price_datetime and price_open columns in comment table:
UPDATE comment AS fc
INNER JOIN price AS p
ON p.ticker_id = fc.ticker_id
AND p.date_time =
( SELECT pi.date_time
FROM price AS pi
WHERE pi.ticker_id = fc.ticker_id
AND pi.date_time >= fc.date_time
ORDER BY pi.date_time ASC
LIMIT 1
) SET
fc.price_datetime = p.date_time,
fc.price_open = p.price_open;
Which we converted to PHP+MySQL hoping for a more efficiency and much faster process:
<?php
ob_flush();
flush();
usleep(160);
$tickers = array();
$stmt = $mysqli->prepare("SELECT ticker_id, date_time FROM flaggedcomment order by ticker_id, date_time");
$stmt->execute(); //Execute prepared Query
$stmt->bind_result($tid, $dt);
$arr_index = 0;
while ($stmt->fetch() ) {
$tickers[$arr_index] = array();
$tickers[$arr_index]["id"] = $tid;
$tickers[$arr_index]["dt"] = $dt;
$arr_index++;
}
/* free result set */
$stmt->free_result();
$record_index = 0;
$flaggedcomment_index = 0;
$sql = "";
// get total tickers
$total_tickers = count($tickers);
echo "Total records: " . $total_tickers . "<br />";
foreach ($tickers as $ticker) { //fetch values
$stmt = $mysqli->prepare("SELECT price_open, date_time FROM price WHERE ticker_id =? AND date_time >=? ORDER BY date_time ASC LIMIT 1;");
$stmt->bind_param("is",$ticker["id"], $ticker["dt"]); // two params: one is integer, and other one is string
$stmt->execute(); //Execute prepared Query
$results = $stmt->get_result();
$myrow = $results->fetch_row();
$set_string = "SET";
// bind values
$price_open = $myrow[0];
$date_time = $myrow[1];
// set initial insert query value
$set_string .= " price_datetime='". $date_time ."'";
$set_string .= ", price_open=". $price_open;
$set_string .= " WHERE ticker_id=". $ticker["id"] ." AND date_time='" . $ticker["dt"] ."'";
if($set_string != ""){
$sql .= "UPDATE flaggedcomment ". $set_string . ";";
}
$idx = $record_index + 1;
if(($record_index + 1) % 100 == 0){
?>
<script>
$('#page-wrap > h1').html("Processing Ticker id #" + <?= $ticker["id"]; ?> + " - Record #" + <?= $idx; ?>);
</script>
<?php
ob_flush();
flush();
usleep(160);
}
$record_index++;
/* free result set */
$stmt->free_result();
} // end while fetch ticker id
$update_flaggedcomment_qry = "LOCK TABLES flaggedcomment WRITE; ". $sql . "UNLOCK TABLES; ";
echo $update_flaggedcomment_qry;
//echo "<br />";
if ($mysqli->multi_query($update_flaggedcomment_qry)) {
// nothing
} else {
echo "Error updating record: " . $mysqli->error . "<br />";
$mysqli->close();
exit;
}
echo "<span style='color:blue;'> <b> Done. </b> </span>";
ob_end_flush();
exit;
?>
Using the MySQL query, if there's no match of ticker_id and date_time from both tables, the fc.price_datetime and fc.price_open columns will show 0000-00-00 00:00:00 and 0.00 values. However, when executing the PHP code, instead of inserting the zero values, it will stop when it encounters its very first "no matching" of ticker_id and date_time and cannot continue. We've spent a long time figuring out on how to fix it, unfortunately, none of the ways we use can fix this.
Any help from the community is definitely much appreciated.
Thank you. :)
You do not check if there is a record returned from price . Hence your code just tries picking the first and second elements of the result array when that array is null. You then likely land up with a statement trying to assign blank to each of the price_datetime and price_open fields. With the price_datetime you have quotes around the empty value and mysql will probably cope with this, but for price_open you do not have quotes around the expected numeric value. Hence you will land up with an invalid update statement (some like the following):-
UPDATE flaggedcomment price_datetime='', price_open= WHERE ticker_id=123 AND date_time='2016-01-01 00:00:00';
As you are executing multiple SQL statements at once to do the updates, I expect that it won't execute any after the invalid statement.
A quick play with your code and the following should work. This checks the returned row and if one isn't found it just uses the default (zero like) values for the 2 fields you want to update.
<?php
ob_flush();
flush();
usleep(160);
$tickers = array();
$stmt = $mysqli->prepare("SELECT ticker_id, date_time FROM flaggedcomment order by ticker_id, date_time");
$stmt->execute(); //Execute prepared Query
$stmt->bind_result($tid, $dt);
$arr_index = 0;
while ($stmt->fetch() )
{
$tickers[$arr_index] = array();
$tickers[$arr_index]["id"] = $tid;
$tickers[$arr_index]["dt"] = $dt;
$arr_index++;
}
/* free result set */
$stmt->free_result();
$record_index = 0;
$flaggedcomment_index = 0;
$sql = "";
// get total tickers
$total_tickers = count($tickers);
echo "Total records: " . $total_tickers . "<br />";
foreach ($tickers as $ticker)
{ //fetch values
$stmt = $mysqli->prepare("SELECT price_open, date_time FROM price WHERE ticker_id =? AND date_time >=? ORDER BY date_time ASC LIMIT 1;");
$stmt->bind_param("is",$ticker["id"], $ticker["dt"]); // two params: one is integer, and other one is string
$stmt->execute(); //Execute prepared Query
$results = $stmt->get_result();
if ($myrow = $results->fetch_assoc())
{
$price_open = $myrow['price_open'];
$date_time = $myrow['date_time'];
}
else
{
$price_open = 0.00;
$date_time = "0000-00-00 00:00:00";
}
$sql .= "UPDATE flaggedcomment SET";
$sql .= " price_datetime='". $date_time ."'";
$sql .= ", price_open=".$price_open;
$sql .= " WHERE ticker_id=". $ticker["id"] ." AND date_time='" . $ticker["dt"] ."';";
$idx = $record_index++;
if(($record_index + 1) % 100 == 0)
{
?>
<script>
$('#page-wrap > h1').html("Processing Ticker id #" + <?= $ticker["id"]; ?> + " - Record #" + <?= $idx; ?>);
</script>
<?php
ob_flush();
flush();
usleep(160);
}
$record_index++;
/* free result set */
$stmt->free_result();
} // end while fetch ticker id
$update_flaggedcomment_qry = "LOCK TABLES flaggedcomment WRITE; ". $sql . "UNLOCK TABLES; ";
echo $update_flaggedcomment_qry;
//echo "<br />";
if ($mysqli->multi_query($update_flaggedcomment_qry)) {
// nothing
}
else
{
echo "Error updating record: " . $mysqli->error . "<br />";
$mysqli->close();
exit;
}
echo "<span style='color:blue;'> <b> Done. </b> </span>";
ob_end_flush();
exit;
?>
However I suspect that looping around the result of one query and doing another query for each row in php will be slower than a well constructed single update query.
If you do want to loop around the results like you are doing now it may be quicker to create a tmp table and insert the rows to that (as you can insert hundreds of rows with a single statement) and then update your flaggedcomment table with a single update statement that joins it to the tmp table
EDIT - If you can post the table declares and a bit of sample data I will have an attempt at doing it in a single SQL statement.
A first attempt (untested) would be:-
UPDATE comment AS fc
INNER JOIN price AS p
ON p.ticker_id = fc.ticker_id
INNER JOIN
(
SELECT *
FROM
(
SELECT fc.ticker_id,
MIN(pi.date_time) AS date_time
FROM comment AS fc
INNER JOIN price AS pi
ON pi.ticker_id = fc.ticker_id
AND pi.date_time >= fc.date_time
GROUP BY fc.ticker_id
) sub1
) sub0
ON p.ticker_id = sub0.ticker_id
AND p.date_time = sub0.date_time
SET fc.price_datetime = p.date_time,
fc.price_open = p.price_open;
This is using the extra seemingly redundant sub query to hopefully bypass a MySQL restriction on updating a table that is also used in a subquery.
How can I print my fetch rows into groups of data?
For example i have these on my database
title category
one number
two number
three number
a letter
b letter
c letter
and I wanted to print it out on a different table.
table1 table2
number letter
one a
two b
three c
here's what I've tried.
$select = "SELECT * FROM `table` ORDER BY `category`";
$result = mysql_query($select);
$current_cat = null;
while ($rows = mysql_fetch_array($result))
{
if ($rows["category"] != $current_cat)
{
$current_cat = $rows["category"];
echo "<p>$current_cat</p>";
}
echo"$rows[title]";
}
the output of these codes is like this
number
one
two
three
letter
a
b
c
but then again, I wanted it to be in separate table.
You could add an if statement to test if the $current_cat is equal to the previous loops $current_cat. Do so by adding a new variable $last_cat, setting it equal to the current iterations $current_cat at the end of the while loop. Here is an example
$select = "SELECT * FROM `table` ORDER BY `category`";
$result = mysql_query($select);
$current_cat = null;
$last_cat = null;
while ($rows = mysql_fetch_array($result)) {
if ($current_cat == null) {
// Create a table with an id name of the first table
echo "<table id='" . $rows["category"] . "'>";
// Write the first row of the table - Category Title
echo "<tr class='categoryTitle'><td>" . $rows["category"] . "</td></tr>";
}
// Set the $current_cat to current loop category value
$current_cat = $rows["category"];
if ($last_cat != null) {
if ($current_cat != $last_cat) {
// Close table from previous $current_cat
echo "</table>";
// Create new table with id name of the category
echo "<table id='" . $rows["category"] . "'>";
// Write the first row of the table - Category Title
echo "<tr class='categoryTitle'><td>" . $rows["category"] . "</td></tr>";
}
}
}
// Write new row in table with the value of the title
echo "<tr><td>" . $rows[title] . "</td></tr>";
// set the $last_cat to the value of $current_cat at the end of the loop
$last_cat = $current_cat;
}
// Close the last table after while loop ends
echo "</table>";
This will allow you to create separate tables based on the category name no matter how many categories you have and allow you to style the tables based on the category name.
I have a table in the following structure...
ID USER_ID INTEREST
1 290 soccer
2 290 tennis
3 290 badminton
4 560 netball
I want to grab all values from the table where the user id is equal to the session user id and assign them as variables.
I have the following which works but displays the data very peculiarly..
$interestsquery = "SELECT * FROM user_interests WHERE user_id = " . $usersClass->userID();
$result = mysql_query($interestsquery);
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$interests[] = $row['interest'];
$interest1 = $interests[1];
$interest2 = $interests[2];
$interest3 = $interests[3];
print $interest1 . " - " . $interest2 . " - " . $interest3;
}
The above however outputs something along the lines of...
- - tennis - - tennis - badminton -
Can anybody see where I'm going wrong?
This should do what you need:
$interestsquery = "SELECT `interest` FROM `user_interests` WHERE `user_id` = " . $usersClass->userID();
$result = mysql_query($interestsquery);
$interests = array();
while(list($interest) = mysql_fetch_array($result))
$interests[] = $interest;
print explode($interests, ' - ');
Think what happens to your loop at the first iteration:
$interest is an empty array
you fetch the first value and put it into $interest[0],
you fill $interest1 with the value that lies into $interest[1] (it is empty)
same for $interest2 and $interest3
you print ""." - ".""." - ".""
in the second run:
$interest is [0=>soccer]
you fetch the second value and put it into $interest[1],
you fill $interest1 with the value that lies into $interest[1] tennis
same for $interest2 and $interest3 (that are still empty)
you print "tennis"." - ".""." - ".""
and so on.
You need print the result when you exit the while loop (and the code is still flawed as
it don't get the value into the index 0 of the array).
An alternative should be:
$interestsquery = "SELECT `interest` FROM `user_interests` WHERE `user_id` = "
. $usersClass->userID();
$result = mysql_query($interestsquery);
$interests = array();
// you fetch just a field, fetch_row will be sufficent
while($interest = mysql_fetch_row($result)) {
array_push($interests, $interest[0]);
}
echo implode(' - ', $interests);
$interests = array();
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
$interests[] = $row['interest'];
}
$int_count = count($interests);
$i=0;
foreach ($interests as $interest) {
$var = 'interest' . ($i + 1);
$$var = $interest;
$i++;
}
print $interest1 . " - " . $interest2 . " - " . $interest3;
I have a MySQL database called "bookfeather" with several tables that contain list books. Under each table, each book has a given number of votes. The PHP code below allows the user to enter in a book title ($entry), and then returns the total number of votes that book has in all tables ($sum).
How could I use PHP to make a 2-column, 25-row table that lists the 25 books in the database with the highest value for $sum (in descending order)?
Thanks in advance,
John
mysql_connect("mysqlv10", "username", "password") or die(mysql_error());
mysql_select_db("bookfeather") or die(mysql_error());
// We preform a bit of filtering
$entry = strip_tags($entry);
$entry = trim ($entry);
$entry = mysql_real_escape_string($entry);
$result = mysql_query("SHOW TABLES FROM bookfeather")
or die(mysql_error());
$table_list = array();
while(list($table)= mysql_fetch_row($result))
{
$sqlA = "SELECT COUNT(*) FROM `$table` WHERE `site` LIKE '$entry'";
$resA = mysql_query($sqlA) or die("$sqlA:".mysql_error());
list($isThere) = mysql_fetch_row($resA);
$isThere = intval($isThere);
if ($isThere)
{
$table_list[] = $table;
}
}
//$r=mysql_query("SELECT * , votes_up - votes_down AS effective_vote FROM `$table[0]` ORDER BY effective_vote DESC");
if(mysql_num_rows($resA)>0){
foreach ($table_list as $table) {
$sql = "SELECT votes_up FROM `$table` WHERE `site` LIKE '$entry'";
$sql1 = mysql_query($sql) or die("$sql:".mysql_error());
while ($row = mysql_fetch_assoc($sql1)) {
$votes[$table] = $row['votes_up'];
$sum += $row['votes_up'];
//echo $table . ': "' . $row['votes_up'] . " for $entry from $table\"<br />";
}
}
}
else{
print "<p class=\"topic2\">the book \"$entry\" has not been added to any category</p>\n";
}
//within your loop over the DB rows
//$votes[$table] = $row['votes_up'];
//afterwards
if($sum>0){
print "<table class=\"navbarb\">\n";
print "<tr>";
print "<td class='sitenameb'>".'<a type="amzn" category="books" class="links2b">'.$entry.'</a>'."</td>";
print "</tr>\n";
print "</table>\n";
//echo "<p class=\"topic3\">".''.$entry.''. "</p>\n";
echo "<p class=\"topic4\">". number_format($sum) . ' votes in total.'."</p>\n";
Try something like this. All of this hasn't been tested so please add comments for changes. I'll work with you to get the code right.
// After getting your array of tables formated like
$tableArray = array("`tableA`", "`tableB`", "`tableC`");
// create a table statement
$tableStatement = implode(", ", $tableArray);
// create a join statement
$joinStatement = "";
for ($i = 1; $i < count($tableArray); $i++) {
if ($joinStatement != "")
$joinStatement .= " AND ";
$joinStatement .= $tableArray[0] . ".site = " . $tableArray[$i] . ".site"
}
$firstTable = $tableArray[0];
$sql = "SELECT SUM(votes_up) FROM " . $tableStatement . " WHERE " . $joinStatement . " AND " . $firstTable . ".site LIKE '" . $entry . "' GROUP BY " . $firstTable . ".site ORDER BY SUM(votes_up) DESC";
Edit --------
I now realize that the query above won't work perfectly because votes_up will be ambiguous. Also because you probably want to be doing joins that grab records that are only in one table. I think the concept is the right direction even though the query may not be perfect.
You can do something like
$selectStatement = "SUM(tableA.votes_up) + SUM(tableB.votes_up) as total_votes_up"
I did something like this recently. In your database, you'll have to rename each field to a corresponding book name.php like (TaleofTwoCities.php). Now on your page that will display the vote results, you'll need to include some php files that will drive the database query on each load. I called mine "engine1.php" and "engine2.php." These will do all your sorting for you.
$query1 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 0,1"));
$query2 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 1,1"));
$query3 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 2,1"));
and so on.. then..
$num1 = "$query1[0]";
$num2 = "$query2[0]";
$num3 = "$query3[0]";
That part sorts your listings by the number of votes from highest to lowest, with url, in your case, being the name of the books(remember you want it to end in .php - you'll see why in a second), and counter being the field that logs your votes.
Make your second engine.php file and add something like this:
$vquery1 = mysql_fetch_row(mysql_query("SELECT counter FROM pages WHERE
url='book1.php'"));
$vquery2 = mysql_fetch_row(mysql_query("SELECT counter FROM pages WHERE
url='book2.php'"));
$vnum1 = "$vquery1[0]";
$vnum2 = "$vquery2[0]";
and so on... Until you get to 25 for both this and engine 1.
Now, in your results page, after you put in the require_once(engine.php) and require_once(engine2.php) at the start of your body, start an HTML table. You only want two columns, so it'll be something like..
<table border=1 cellspacing=0 cellpadding=0>
<tr>
<?php include $num1; ?>
</tr>
<tr>
<?php include $num2; ?>
</tr>
And so on... By naming your field with "book1.php" and including the engines, $num1 will change to a different .php file depending on votes from high to low. Now all you have to do is make small php files for each book like so - no headers or anything because you're inserting it into the middle of html code already:
<td style="width:650px;"><center><img src="images/book1.jpg" alt="" border="none"
/></a></center></td>
<td style="width:150px;">Votes: <?php echo $vnum1;?></td>
And there you have it. A code that will dynamically give you results from high to low depending on the number of votes each book has.