Loop the subcategories, subcategories, etc - php

$sth = $db->query("SELECT * FROM categories WHERE parent = 0");
$sth->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $sth->fetch()) {
echo $row['title'] . '<br />';
$sth2 = $db->prepare("SELECT * FROM categories WHERE parent = ?");
$sth2->bindParam(1, $row['id']);
$sth2->execute();
while ($row2 = $sth2->fetch()) {
echo '..' . $row2['title'] . '<br />';
$sth3 = $db->prepare("SELECT * FROM categories WHERE parent = ?");
$sth3->bindParam(1, $row2['id']);
$sth3->execute();
while ($row3 = $sth3->fetch()) {
echo '....' . $row3['title'] . '<br />';
}
}
}
As you can see I have 'hard coded' every while loop for mainly a "main category", 'a subcategory' and finally it's subcategory.
However I feel that I could change this, to automatically, loop the subcategories in the subcategories, if there are such.
The structure is simple of my SQL:
id
parent
title
description
I am clueless how I should solve this little problem... A while loop over a if-statement or something? Help me out.

What you can do if the number of categories is not too big, is get all categories in one go from the database and then build a multi-dimensional array in php.
See this question and the answers for more details.

Related

How to show sql select parent and child in php

Maybe a simple question, but after hours of reading i still didn't find an answer.
I'm trying to get the values of subrow next to those of parent row, without constantly repeating parent row:
For example:
Table 1: ParentId = 1, ParentName = ParentName
Table 2:
ChildId = 1, ParentId = 1, ChildName = ChildName1
ChildId = 2, ParentId = 1, ChildName = ChildName2
The result with JOIN currently is:
ParentId, ParentName, ChildId, ChildName1
ParentId, ParentName, ChildId, ChildName2
But i would like to display the data like:
<div>Div with parent name</div>
<div>Div with ChildName1</div>
<div>Div with ChildName2</div>
<div>Div with parent name2</div>
<div>Div with ChildName1</div>
<div>Div with ChildName2</div>
etc...
Can anyone tell me how to get to this?
Something like
echo$Parent1 foreach child as $child echo$ChildName?
You can sort by parent ID, then check if it has changed. If it has changed output the name of the parent. Something like this:
$query = "query selecting data with join... ORDER BY ParentId";
$result = $mysqli->query($query);
$lastParent = 0;
while ( $row = $result->fetch_assoc($result) )
{
if ( $row['ParentId'] != $lastParent )
{
echo '<div>' . $row['ParentName'] . '</div>';
}
$lastParent = $row['ParentId'];
echo '<div>' . $row['ChildName'] . '</div>';
}
Using that the parent name will only output when the ID changes, and as we're ordering by ID all the children will be grouped by their Parent and output together.
Issue fixed with following code
$result = mysqli_query($link, "SELECT * FROM TestParent a
LEFT JOIN TestChild b ON a.ParentId = b.ParentId
ORDER BY a.ParentId ASC, b.ChildName ASC");
$lastParent = 0;
while($row = mysqli_fetch_assoc($result))
{
if ( $row['ParentId'] != $lastParent ) {
echo '<div>' . $row['ParentName'] . '</div>';
}
$lastParent = $row['ParentId'];
echo '<div>' . $row['ChildName'] . '</div>';
}

PHP MySQL - foreach loop with if to display subset list within key list

I am trying to display records of venues, with a listing of rooms within each unique record. I have two tables, a venue_lookup table and a venue_lookup_room table. using the slow example I am struggling to ONLY populate each venue with the rooms that are contained within. I am able to echo the rooms into the venues, but I am struggling to restrict the rooms to ONLY appear with their unique parent venue. There is something simple that i am not seeing, I just know it.
//VENUE w VENUE ROOMS ARRAY TEST 2
$selCity = $_GET['theOption']; //Per Comment below modified $_POST to $_GET
$result5 = mysql_query("SELECT *
FROM lookup_venue_room INNER JOIN lookup_venue
ON lookup_venue_room.venue_name = lookup_venue.venue_name
WHERE lookup_venue.venue_city = '$selCity'
AND lookup_venue.venue_name = lookup_venue_room.venue_name") or die('ERROR' . mysql_error());
$roomNames = array();
$venueNames =array();
while($row2 = mysql_fetch_array($result5)) {
$roomNames[] = $row2['venue_room_name'];
$venueNames[] = $row2['venue_name'];
}
$result6 = mysql_query("SELECT * FROM lookup_venue WHERE lookup_venue.venue_city = '$selCity'")
or die('ERROR:' . mysql_error());
while($row = mysql_fetch_array($result6))
{
echo '<h3>' . $row['venue_name'];
echo '<select name="rooms">';
$venueNameOrig = $row['venue_name'];
foreach ($roomNames as $roomName) {
if ($row2['venue_name'] == $venueNameOrig ) {
echo '<option value="' . $roomName . '" selected="selected">' . $roomName . '</option>';
}
else {
echo '<option value="None">Non-venue-name-match</option>';
}
}
echo '</select>';
}

php-sql groups data with the same category

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.

PHP MySQL Display counts

I have this query for counting the number of items in a category:
SELECT category, COUNT(*) AS category_count FROM users GROUP BY category
Which creates results looking like:
category category_count
========== ================
X 3
Y 2
Now, In PHP I want to display the counts of the categories. For example, I might want to echo the count from category X, how would I do it?
Thanks in advance
Assuming $result holds the result of your query:
while ($row = mysql_fetch_array($result))
{
echo 'Category: ' . $row['category'];
if ($row['category'] == 'X')
{
echo ' Count: ' . $row['category_count'];
}
echo '<br/>';
}
$res = mysql_query("SELECT category, COUNT(*) AS category_count FROM users GROUP BY category");
while($row = mysql_fetch_assoc($res)){
echo $row['category'].": ".$row['category_count']."<br/>";
}
$result = mysql_query("SELECT category, COUNT(*) AS category_count FROM users GROUP BY category");
while ($row = mysql_fetch_array($result, MYSQL_NUM)) {
{
if ( $row['category'] == 'x' )
{
echo $row['category_count'];
}
}
while ($row = mysql_fetch_array($result))
{
echo 'Category: ' . $row['category'] . ' Count:' . $row['category_count'];
echo "<br>";
}
It would be better if you use the where clause in your query.
SELECT COUNT(*) AS category_count FROM users WHERE category = 'x'
$conn = mysql_connect("address","login","pas s");
mysql_select_db("database", $conn);
$Var = mysql_query("query");
While ($row = mysql_fetch_assoc($var) { echo $var["column"] }.

Retrieving values from several tables in a MySQL database

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.

Categories