Efficient Method To Display Group Title Once — PHP/MySQL/jQuery - php

There are three tables in MySQL: Employees, Branches, Departments. I need information to appear in the following way:
ATLANTA Branch Delivery Department Phillip J. Fry Phone: 123456
Engineering Department Turanga Leela Phone: 123457
Bender Rodriguez Phone: 123458
The simple PHP code currently:
1) Takes rows from three tables (simple SELECT query with JOIN)
2) Puts them in row (mysql_fetch_assoc)
3) Displays using the PHP While loop
The result is then like this:
ATLANTA Branch Delivery Department Phillip J. Fry Phone: 123456
ATLANTA Branch Engineering Department Turanga Leela Phone: 123457
ATLANTA Branch Engineering Department Bender Rodriguez Phone: 123458
What technique (JS, jQuery, Ajax) or method can you recommend so I can pull row information using only one query and not duplicate the Branch name and Department name?
UPDATE: If I put the branch name outside the loop (using While loop), there would be multiple loops: 1) To get a branch, 2) To get a department, 3) To get all employees in that department. Loop.
UPDATE: Sharing the code:
<?php
// Create connection
$connection = mysql_connect('localhost','root', '') or die('Connection error.');
mysql_query("SET NAMES 'utf8'", $connection);
mysql_select_db("eReference");
// Check Employees
$query = "SELECT Employees.fName, Employees.lName, Department.deptName, Branch.branchName, ".
"FROM Employees ".
"LEFT JOIN Department ".
"ON Employees.department = Department.id ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.id ;";
$result = mysql_query($query, $connection) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
?>
<h2><?php echo $row['branchName']; ?></h2>
<?php if ($row['deptName']) echo "<h3>" . $row['deptName'] . "</h3>"; ?>
<h4><?php echo $row['fName'] . " " . $row['lName']; ?></h4></p>
<?php
}
?>

<?php
$i = 1; // to be incremented after printing branchName once
while ($row = mysql_fetch_assoc($result)) {
if($i == 1) { ?>
<h2><?php echo $row['branchName']; $i ++; ?></h2>
<?php } ?>
<?php if ($row['deptName']) echo "<h3>" . $row['deptName'] . "</h3>"; ?>
<h4><?php echo $row['fName'] . " " . $row['lName']; ?></h4></p>
<?php } ?>
Just add a variable $i = 1 and check before printing if it is equal to 1. After printing it for first time, increment it.
It is just addition of an if statement.
Hope this helps.

This is how I would do it.
Create a multi-dimensional array with the data, and iterate through the array to render the output.
This will not be the most efficient in terms of memory usage, but unless you have thousands of rows of data, it probably won't be an issue.
The benefit of this, is that the html rendering code is much simpler and easier to understand, plus sql and html are not intermingled. (which is good for code maintenance)
<?php
// Create connection
$connection = mysql_connect('localhost','root', '') or die('Connection error.');
mysql_query("SET NAMES 'utf8'", $connection);
mysql_select_db("eReference");
// Check Employees
$query = "SELECT Employees.fName, Employees.lName, Department.deptName, Branch.branchName, ".
"FROM Employees ".
"LEFT JOIN Department ".
"ON Employees.department = Department.id ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.id ;";
// note you probably want to add an order by statement here too, to ensure consistent sorting
$result = mysql_query($query, $connection) or die(mysql_error());
$data = array();
// build a multi-dimensional array from the result set
while ($row = mysql_fetch_assoc($result)) {
$data[($row['branchName'])][($row['deptName'])][] = array(
'name' => "{$row['fName']} {$row['lName']}",
'phone' => $row['phone'] // add phone, doesn't exist in original query, but just to illustrate how it would work
);
}
// sql finishes here
?>
<?php
// html rendering
// use htmlentities to escape any html chars, such as < > etc
foreach ($data as $branchName => $departments) {
echo '<h2>',htmlentities($branchName),'</h2>';
foreach ($departments as $deptName => $employees) {
foreach ($employees as $employee) {
echo '<h3>',htmlentities($deptName),'</h3>';
echo '<h4>',htmlentities($employee['name']),'</h4>';
echo '<h4>',htmlentities($employee['phone']),'</h4>';
}
}
}
?>

The result gotten from your sql should be an array so use a while loop to iterate throw the array while echo the result of the current index

Maybe this will work..
<?php
$deptName;
while($row = mysql_fetch_assoc($result))
{
if ($row['deptName'])
{
if ($deptName != $row['deptName'])
{
echo "<h3>" . $row['deptName'] . "</h3>";
$deptName = $row['deptName'];
}
}
}
?>

$result = mysql_query($query, $connection) or die(mysql_error());
$newarray = array();
$i = 0;
while ($row = mysql_fetch_assoc($result)) {
$newarray[$i]['deptName'] = $row['deptName'];
$newarray[$i]['fName'] = $row['fName'];
$newarray[$i]['lName'] = $row['lName'];
$i++;
}
<h2><?php echo $newarray[0]['branchName']; ?></h2>
while($newarray){
?>
<?php if ($newarray['deptName']) echo "<h3>" . $newarray['deptName'] . "</h3>"; ?>
<h4><?php echo $newarray['fName'] . " " . $newarray['lName']; ?></h4></p>
}
?>

So, this is what it did:
$query = "SELECT Employees.lName, Employees.fName, Employees.mName, Position.position, ".
"department.deptName, department.deptId, ".
"Branch.branchName, Branch.branchId, ContactInformation.* ".
"FROM Employees ".
"LEFT JOIN Position ".
"ON Employees.position = Position.id ".
"LEFT JOIN Department ".
"ON Employees.department = Department.deptId ".
"LEFT JOIN Branch ".
"ON Employees.branch = Branch.branchId ".
"LEFT JOIN ContactInformation ".
"ON Employees.contactInformation = ContactInformation.id ".
"ORDER BY Employees.branch, Employees.department ASC;";
$result = mysql_query($query, $connection) or die(mysql_error());
$arrayOfEmployees = array();
while ($row = mysql_fetch_assoc($result)) {
$arrayOfEmployees[($row['branchName'])][($row['deptName'])][] = array(
'lName' => $row['lName'],
'fName' => $row['fName'],
'mName' => $row['mName'],
'position' => $row['position'],
'lPhone1' => $row['lPhone1'],
'lPhone2' => $row['lPhone2'],
'mPhone' => $row['mPhone'],
'fax' => $row['fax'],
'office' => $row['office'],
'email' => $row['email']
);
}
foreach($arrayOfEmployees as $branchName => $arrayOfDepartments) {
echo "<h2>".$branchName."</h2>";
foreach($arrayOfDepartments as $deptName => $arrayOfEmployeeContacts) {
echo '<h3>',htmlentities($deptName),'</h3>';
foreach($arrayOfEmployeeContacts as $employeeContacts) {
echo "<h4>".$employeeContacts["lName"]." ".$employeeContacts["fName"]." ".$employeeContacts["mName"]."</h4>";
echo "<p>";
if($employeeContacts["position"]) echo $employeeContacts["position"]."<br>";
$num = $employeeContacts["lPhone1"];
if($employeeContacts["lPhone1"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["lPhone2"];
if($employeeContacts["lPhone2"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["mPhone"];
if($employeeContacts["mPhone"]) echo "+".substr($num,0,1)." (".substr($num,1,3).") "." ".substr($num,4,3)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
$num = $employeeContacts["fax"];
if($employeeContacts["fax"]) echo "+".substr($num,0,1)." (".substr($num,1,4).") "." ".substr($num,5,2)."-".substr($num,7,2)."-".substr($num,9,2)."<br>";
if($employeeContacts["email"]) echo "".$employeeContacts["email"]."<br>";
if($employeeContacts["office"]) echo "Кабинет — ".$employeeContacts["office"];
echo "</p>";
}
}
}
Tested. The solution works well dynamically — just add more branches and departments into the database. Here is the efficiency check against the method I originally used (in microseconds):
Array-based Original
1 1.015 1.012
2 1.016 1.02
3 1.026 1.013
4 1.015 1.002
5 1.026 1.02
6 1.014 1.02
7 1.013 1.019
8 1.005 1.014
9 1.013 1.006
10 1.021 1.015
Average 1.0164 1.0141

Related

How to echo all rows with certain aspect

I have two tables. They are connected via a one (userinfo) to many (achievements) foreign key relationship. What I am attempting to do below is echo all the rows which have the given $usrid. This could be more than one.
Unfortunately, It only echos content one of the rows. How can I change it to echo all the rows where a a certain userid is present?
<!DOCTYPE HTML>
<head>
<?php $usrid = $_GET['usrid'];
$connection = #mysqli_connect("localhost","root","","Rain")
OR die('Could not connect' .
mysqli_connect_error());
$query = "SELECT usrid, username, oldname, languages, joindate, art, hunting, frontwebdev, backwebdev, writing, programming, se, smm, pentesting, timezone, availability, reliability, profilePicture FROM userinfo WHERE usrid='" . $usrid . "';";
$response = #mysqli_query($connection,$query);
$row = #mysqli_fetch_array($response);
$username = $row['username'];
$achvquery = "SELECT achieveid, usrid, achievementname, achievementdescr, timestamp FROM achievements WHERE usrid=" . $usrid . ";";
$achvresponse = #mysqli_query($connection,$achvquery);
$achvrow = #mysqli_fetch_array($achvresponse);
$achvtitle = $achvrow['achievementname'];
$achvdescr = $achvrow['achievementdescr'];
?>
<title>
All Achievements
</title>
</head>
<body>
<span> <?php echo "<span> " . $username . "s OD Achievement History "; ?> </span>
<span id="newAchvLink"> <?php echo "<a id='addNewLink' href='addachievement.php?usrid=" . $usrid . "'> Add new</a>"; ?></span>
<br /> <?php echo "<h2> Achv: </h2> <h3 class='achvtitle'>" . $achvtitle . "</h3>"; echo $achvdescr;?><br /><br />
</body>
</html>
You can use while loop to print all row
$query = "SELECT usrid, username, oldname, languages, joindate, art, hunting, frontwebdev, backwebdev, writing, programming, se, smm, pentesting, timezone,
availability, reliability, profilePicture FROM userinfo WHERE usrid='" . $usrid . "';";
$response = #mysqli_query($connection,$query);
while ($row = #mysqli_fetch_array($response))
{
echo $row['username'];
}
Where you have the PHP echo statement you can replace it with something like...
while($row = $result->fetch_assoc($response)) {
echo "<span> " . $username . "s Op Achievement History ";
You should look at JOIN to simplify all of this for you.
https://www.w3schools.com/sql/sql_join.asp
This is a pretty good/easy to understand usage of PHP Loops.
https://www.tutorialspoint.com/php/php_loop_types.htm
first table query
while loop
{
$userid=first_table_data['user_id'];
2nd table query where userid=$userid
while loop
{
}
all value save in array
}
print value

Convert MySQL query loop to PHP array (table)

I have a system which looks through a database, creates a table of a specified size and then fills the cells with either full or empty depending if there is data in the database for that specific location.
At the moment it works by doing a SQL query for each cell and then populating, but I have 30,000+ records in the database and even with a LIMIT 1 it's still taking about 5 second to load the table.
I'm wondering if dumping the entire contents into a PHP array and then querying that way would be better, but can't work out the best way to sort it, any tips welcome.
Current (working) code:
echo <<<EOD
<table class="racktable"><tr>
<td colspan ="$colspan">Rack Details </td>
</tr>
<tr>
<td colspan ="$colspan"><center>Edit Rack / Empty Rack / Delete Rack</center> </td>
</tr>
EOD;
//Loop through rows, creating a <tr> for each in the table
for ($row1 = 1; $row1 <= $rows; $row1++) {
echo <<<EOD
<tr><td><a name="$row1"></a>$row1</td>
EOD;
//Loop through columns creating <td> within <tr>
for ($col1 = 1; $col1 <= $columns; $col1++) {
$sql2 = "SELECT ID, sample, rack, srow, col, location FROM samples WHERE srow = $row1 and col = $col1 and location = '$location' and rack = '$rack' LIMIT 1";
if (!$result2 = $db->query($sql2)) {
die('There was an error running the query [' . $db->error . ']');
}
$row3 = $result2->num_rows;
//If location is empty, colout green
if ($row3 == 0) {
echo "<td style=\"background-color: #A3CD81\">" . $col1 . "</td>";
}
else {
//Location is not empty, colour red and link to sample
while ($row2 = $result2->fetch_assoc()) {
$columns1 = $row2['col'];
$ID = $row2['ID'];
$tooltip = $row2['sample'];
$queryStr = $_SERVER['QUERY_STRING'];
$spath = $_SERVER['PHP_SELF'] . "?" . $queryStr . "&sample=" . $ID;
echo <<<EOD
<td style="background-color: #FF0000" title="$tooltip">$col1 <img src="icon.png" style="border: 0" alt=""></td>
EOD;
}
}
}
echo "</tr>";
}
echo "</table>";
You can convert all data from DB directly into a php array with this code:
while(($PHPToPHP[] = mysql_fetch_assoc($SqlResult )) || array_pop($dataToPHP));
may be work for your code:
while(($dataToPHP[] = $result2->fetch_assoc()) || array_pop($dataToPHP))
And to see what it does use print_r($dataToPHP).
To manage the errors die('There was an error running the query [' . $db->error . ']'); and if ($row3 == 0) { echo "<td style=\"background-color: #A3CD81\">" . $col1 . "</td>";} to colorize, you need to make some tests to correctly manage.
You need an array with index like your where
SELECT ID, sample, rack, srow, col, location
FROM samples
WHERE srow = $row1 and col = $col1 and location = '$location' and rack = '$rack'
LIMIT 1";
Your array looks like:
$samples = array(
"$row1:$col1:$location:$rack" => array( 'id' => $id, 'sample' => $sample
)
Or you can use some hash array like:
$samples = array(
md5( "$row1:$col1:$location:$rack" ) => array( 'id' => $id, 'sample' => $sample
)
Insert all values once - than get it like
$val = $samples["$row1:$col1:$location:$rack"];
// or from hash array
$val = $samples[md5( "$row1:$col1:$location:$rack" )];

Echo array based on distinct key

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);
}

Looping through column fields in MySQL with PHP

I'm building a food menu on a webpage. This menu includes drink items like Wine and Beer. Currently, they are categorized by Red or White and the type of wine (Pinot Grigio, Chardonnay, etc.). I have entered these wine items into a MySQL database with the following columns/values:
id(int), name(varchar), type(varchar), price_bottle(decimal), price_glass(decimal), red(bool)
My Current code:
$result = mysql_query("SELECT * FROM Wines WHERE type = 'Pinot Grigio' ");
while($row = mysql_fetch_array($result)) {
$name = $row['name'];
$type = $row['type'];
$price_bottle = $row['price_bottle'];
$price_glass = $row['price_glass'];
echo
"<div class='foodmenu-item'>
<div class='foodmenu-text'>
<h2>" . $type . "</h2>
<p>" . $name . "</p>
</div>
<div class='foodmenu-price'>
<p>$" . $price_bottle . " / " . $price_glass . "</p>
</div>
</div>";
}
Which is fine if I wanted to display each item out individually, but I want to Group by 'type' of wine (Pinot Grigio, Chardonnay, etc.) and then list each name of the wine under that 'type' so my CSS looks neat and organized.
For Example:
PINOT GRIGIO
Nobllissimo
Riff
CHARDONNAY
The Crusher
Bogle
Using the "GROUP BY" SQL syntax only displays the first result with my current code. All my attempts at making a foreach statement result in error, I'm not sure where to turn next.
How can I achieve this?
good manner is don't simply use "*", but list of columns
(reason: select only data which realy want to use - better performance, second if you later want add or change columns in the table then your life will be simplier ;-) )
I think you can try, select all from small table and only sort the data - type and name, then in while cycle do it group about type for your menu. Then you need only one query send to database and have all of it. Assumption is Wines is only small table, because select all consume a memory.
SELECT type, name, price_bottle, price_glass
FROM Wines
ORDER BY type, name;
Have you tries using 2 queries nested? Like this:
$result = mysql_query("SELECT DISTINCT(type) FROM Wines ORDER BY type");
while($row = mysql_fetch_array($result)) {
$type = $row['type'];
echo "<div class='foodmenu-item'>
<h2>" . $type . "</h2>";
$result2 = mysql_query("SELECT * FROM Wines WHERE type = '".type."' ");
while($row2 = mysql_fetch_array($result2)) {
$name = $row2['name'];
$price_bottle = $row2['price_bottle'];
$price_glass = $row2['price_glass'];
echo "
<div class='foodmenu-text'>
<p>" . $name . "</p>
</div>
<div class='foodmenu-price'>
<p>$" . $price_bottle . " / " . $price_glass . "</p>
</div>";
}
echo "</div>";
}

php/mysql: Append 2 or more foreign keys to one 'query'?

My solution to this is at the bottom
My issue is: I am trying to display foreign key data, but because there is more than one foreign key, I am getting a 'duplicate' query for each of the foreign keys.
http://i.imgur.com/Gfqx497.png
As you can see, I can query the correct data, but I don't know how to attach the other foreign key data to the same 'one line output'.
I've been lurking stackoverflow for a while to find an answer to my problem and I'm at a wits end. I have found quite a number of threads, such as the two links below, where I believe people are asking the same thing, however I can't seem to wrap my head around getting the solution to work in my case. From my understanding, I need to be using aliases for the tables, however I've tried multiple different interpretations of the solutions and can't recreate the solution.
How do I merge two or more rows based on their foreign key
mysql query 2 foreign keys
--
I've got two tables ('Minions and Ability'), one of which has four foreign keys linking to the other.
http://i.imgur.com/ctpFHur.png
This is the php code that I'm using for the query, which is mostly taken from PHP and MySQL Web Development 4th Edition (Welling, Thomson) which I purchased to get me started with php and mysql.
$query = "SELECT minions.name, minions.summon, minions.attack,
minions.health, minions.race, minions.rarity,
minions.ability1, minions.ability2, minions.ability3,
minions.ability4, minions.imagebig,
ability.ability
AS ability FROM minions
INNER JOIN ability on
minions.ability1 = ability.abilityid
OR minions.ability2=ability.abilityid";
//Only trying for 2 foreign keys to try get it to work
$result = $db->query($query);
$num_results = $result->num_rows;
echo "<p>Number of items found: ".$num_results."</p>";
for ($i=0; $i <$num_results; $i++){
$row = $result->fetch_assoc();
//echo "<p><strong>".($i+1).". Name: ";
echo "<p><strong>";
echo htmlspecialchars(stripslashes($row['name']));
echo "</strong><br />Summoning cost: ";
echo stripslashes($row['summon']);
echo "<br />Attack: ";
echo stripslashes($row['attack']);
echo "<br />Health: ";
echo stripslashes($row['health']);
echo "<br />Race: ";
echo stripslashes($row['race']);
echo "<br />Rarity: ";
echo stripslashes($row['rarity']);
//if (stripslashes($row['ability'] != NULL)){
echo "<br />Abilty: ";
echo stripslashes($row['ability']);
//}
echo "<br />";
$imageMinion = stripslashes($row['imagebig']);
// $iwidth = 25;
// $iheight = 100;
// echo '<img src="img/'.$imageMinion.'.png" style="width:'.$iwidth.'px;height:'.$iheight.'px;">';
//echo "<br />";
echo '<img src="img/'.$imageMinion.'.png">';
echo "</p>";
Could someone please guide me to getting this to display correctly? I've tried to follow the other solutions and just can't seem to get the alias naming correct, if I'm correct in thinking that is the solution.
========EDIT REGARDING ANSWER FROM verbumSapienti===========
I am embarrassingly unable to get your Answer to work. This is how the code looks.
$query = "SELECT minions.name, minions.summon, minions.attack, minions.health,
minions.race, minions.rarity, minions.ability1, minions.ability2,
minions.ability3, minions.ability4, minions.imagebig,
ability.ability
AS ability
FROM minions
INNER JOIN ability
ON minions.ability1 = ability.abilityid
OR minions.ability2 = ability.abilityid
OR minions.ability3 = ability.abilityid
OR minions.ability4 = ability.abilityid";
$result = $db->query($query);
$num_results = $result->num_rows;
echo "<p>Number of items found: ".$num_results."</p>";
for ($i=0; $i <$num_results; $i++){
$row = $result->fetch_assoc();
$abilities = array('ability1', 'ability2', 'ability3', 'ability4');
foreach($abilities as $ability)
{
$q = "SELECT $ability FROM minions WHERE name={$row['name']}";
$result = $db->query($q);
$row2 = $result->fetch_assoc();
$abilitiesArr[] = $row2[$ability];
}
echo "<p><strong>";
echo htmlspecialchars(stripslashes($row['name']));
echo "</strong><br />Summoning cost: ";
echo stripslashes($row['summon']);
echo "<br />Attack: ";
echo stripslashes($row['attack']);
echo "<br />Health: ";
echo stripslashes($row['health']);
echo "<br />Race: ";
echo stripslashes($row['race']);
echo "<br />Rarity: ";
echo stripslashes($row['rarity']);
foreach($abilitiesArr as $ability)
{
$q = "SELECT $ability FROM ability";
$result = $db->query($q);
$row = $result->fetch_assoc();
echo "<br />Ability: $row";
}
/*if (stripslashes($row['ability'] != NULL)){
echo "<br />Abilty: ";
echo stripslashes($row['ability']);
}*/
echo "<br />";
$imageMinion = stripslashes($row['imagebig']);
echo '<img src="img/'.$imageMinion.'.png">';
echo "</p>";
}
I've tried changing around a few things and haven't had any success. As is, I get the following error:
Fatal error: Call to a member function fetch_assoc() on a non-object in D:\Xampp\htdocs\ocduels\results.php on line 87
Which is:
$row2 = $result->fetch_assoc();
In:
$abilities = array('ability1', 'ability2', 'ability3', 'ability4');
foreach($abilities as $ability)
{
$q = "SELECT $ability FROM minions WHERE name={$row['name']}";
$result = $db->query($q);
$row2 = $result->fetch_assoc();
$abilitiesArr[] = $row2[$ability];
}
::MY SOLUTION TO THIS::
This seems to work. I don't think its efficient, but its enough to allow me to continue learning. Thank you for all the responses. This allows me to find a 'Minion' and only have one instance of the 'Minion' when there is more than 1 Foreign Key with data.
$query = "SELECT
m.name as m_name,
m.summon as m_summon,
m.attack as m_attack,
m.health as m_health,
m.race as m_race,
m.rarity as m_rarity,
m.ability1 as m_ability1,
m.ability2 as m_ability2,
aa.ability as a_ability,
ab.ability as b_ability,
m.imagebig as m_imagebig
FROM minions m
LEFT JOIN ability aa
ON m.ability1 = aa.abilityid
LEFT JOIN ability ab
ON m.ability2 = ab.abilityid";
$result = $db->query($query);
$num_results = $result->num_rows;
echo "<p>Number of items found: ".$num_results."</p>";
for ($i=0; $i <$num_results; $i++){
$row = $result->fetch_assoc();
echo "<p><strong>";
echo htmlspecialchars(stripslashes($row['m_name']));
echo "</strong><br />Summoning cost: ";
echo stripslashes($row['m_summon']);
echo "<br />Attack: ";
echo stripslashes($row['m_attack']);
echo "<br />Health: ";
echo stripslashes($row['m_health']);
echo "<br />Race: ";
echo stripslashes($row['m_race']);
echo "<br />Rarity: ";
echo stripslashes($row['m_rarity']);
if (stripslashes($row['a_ability'] != NULL)){
echo "<br />Ability 1: ";
echo stripslashes($row['a_ability']);
}
if (stripslashes($row['b_ability'] != NULL)){
echo "<br />Ability 2: ";
echo stripslashes($row['b_ability']);
}
echo "<br />";
$imageMinion = stripslashes($row['m_imagebig']);
echo '<img src="img/'.$imageMinion.'.png">';
echo "</p>";
}
Try DISTINCT keyword to restrict duplicate values.
SELECT DISTINCT minions.name, minions.summon, minions.attack,
minions.health, minions.race, minions.rarity,
minions.ability1, minions.ability2, minions.ability3,
minions.ability4, minions.imagebig,
ability.ability
AS ability FROM minions
INNER JOIN ability on
minions.ability1 = ability.abilityid
OR minions.ability2=ability.abilityid";
you could try a subquery that prints only the ability text for each ability ID contained in each minion's attributes, maybe something along the lines of:
$abilities = array('ability1', 'ability2', 'ability3', 'ability4');
foreach($abilities as $ability)
{
$q = "SELECT $ability FROM minions WHERE name={$row['name']}";
$result = $db->query($q);
$row2 = $result->fetch_assoc()
$abilitiesArr[] = $row2[$ability];
}
then replace
echo "<br />Abilty: ";
echo stripslashes($row['ability']);
with
foreach($abilitiesArr as $ability)
{
$q = "SELECT $ability FROM ability";
$result = $db->query($q);
$row = $result->fetch_assoc()
echo "<br />Ability: $row";
}

Categories