PHP Output data from 3 different tables - php

I'm trying to display a HTML table with information from 3 different tables in my mysql DB. However I am unsure on how to display the information from the third table.
Currently what I am using is:
$SQL = "SELECT members.*, exp.*, lvl.*
FROM members
INNER JOIN exp ON members.id = exp.member_id
INNER JOIN lvl ON members.id = lvl.member_id
ORDER BY lvl.level DESC,
lvl.total DESC, xp.total DESC";
$result = mysql_query($SQL) or die(mysql_error());
$count = 1;
while ($row = mysql_fetch_assoc($result)) {
$level = $row['level'];
$exp = $row['exp.overall'];
}
the $level is from the second table which grabs correctly, and the $exp is what I want to grab from the third table which is "exp" but it doesn't return anything
How can I change this because at the moment it just seems to be focusing on the data from the "lvl" table when using $row[]
Edit: Both the lvl and exp tables have a row in called 'overall' which is why using $row['overall'] doesn't return what I want as it returns the data from lvl table rather than exp.

First off I believe you have a typo in your last order column: should be exp.total DESC.
Secondly, unless you specify the columns to be named with dot notation explicitly they will retain their column names so try changing the last line to:
$exp = $row['overall'];.
Also consider using mysqli or PDO.

Related

Retrieve certain row from array depending on a value

Echo out the right row from an array compiled from a mysql database.
I have extracted information from a database (locations) containing three fields: id, name, city into an array called $array. I want to loop through another database (events) in which the id's from the first database (locations) are stored in a field. When looped I want to display the corresponding name and city from the locations database.
Is this possible without having to fetch information every loop?
This is my first try
$query = "Select id, name, city FROM locations WHERE typ = '1'";
$result = mysqli_query($conn, $query);
$row = array();
while ($row = mysqli_fetch_assoc($result)) {
$array[] = $row;
}
And then I thought I could specify the key myself like this:
$query = "Select id, name, city FROM locations WHERE typ = '1'";
$result = mysqli_query($conn, $query);
$row = array();
while ($row = mysqli_fetch_assoc($result)) {
$array[$row['id']] = $row;
}
But I couldn't figure out how to echo the right row.
You can join both tables in a single query, using something like this:
Select locations.id, locations.name, locations.city, events.name
FROM locations
JOIN events ON locations.id = events.id
WHERE locations.typ = '1'
The events.id on the JOIN statement is assuming that this is the column name of the id in the events table. I also made the assumption that these are the two fields that will match between the two tables. Adjust accordingly if your matching criteria is different.
The SELECT statement was modified to pull columns from both tables. Add whichever fields are relevant to your needs.

I need to nest 2 arrays so that I can echo order header as well as order item details

I have updated my original post based on what I learned from your comments below. It is a much simpler process than I originally thought.
require '../database.php';
$pdo = Database::connect();
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM Orders WHERE id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($id));
$data = $q->fetch(PDO::FETCH_ASSOC);
echo 'Order Num: ' . $data['id'] . '<br>';
$sql = "SELECT * FROM Order_items
JOIN Parts ON Parts.id = Order_Items.part_id
WHERE Order_Items.orders_id = 430";
$q = $pdo->prepare($sql);
$q->execute(array($line_item_id));
$data = $q->fetch(PDO::FETCH_ASSOC);
while ($data = $q->fetch(PDO::FETCH_ASSOC))
{
echo '- ' . $data['part_num'] . $data['qty'] . "<br>";
}
Database::disconnect();
Unfortunately, only my first query is producing results. The second query is producing the following ERROR LOG: "Base table or view not found: 1146 Table 'Order_items' doesn't exist" but I am expecting the following results.
Expected Results from Query 1:
Order Num: 430
Expected Results from Query 2:
- Screws 400
- Plates 35
- Clips 37
- Poles 7
- Zip ties 45
Now that I understand where you are coming from, let's explain a couple of things.
1.PDO and mysqli are two ways of accessing the database; they essentially do the same things, but the notation is different.
2.Arrays are variables with multiple "compartments". Most typical array has the compartments identified by a numerical index, like:
$array[0] = 'OR12345'; //order number
$array[1] = '2017-03-15'; //order date
$array[2] = 23; //id of a person/customer placing the order
etc. But this would require us to remember which number index means what. So in PHP there are associative arrays, which allow using text strings as indexes, and are used for fetching SQL query results.
3.The statement
$data = $q->fetch(PDO::FETCH_ASSOC)
or
$row = $result->fetch_assoc()
do exactly the same thing: put a record (row) from a query into an array, using field names as indexes. This way it's easy to use the data, because you can use field names (with a little bit around them) for displaying or manipulating the field values.
4.The
while ($row = $result->fetch_assoc())
does two things. It checks if there is a row still to fetch from the query results. and while there is one - it puts it into the array $row for you to use, and repeats (all the stuff between { and }).
So you fetch the row, display the results in whatever form you want, and then loop to fetch another row. If there are no more rows to fetch - the loop ends.
5.You should avoid using commas in the FROM clause in a query. This notation can be used only if the fields joining the tables are obvious (named the same), but it is bad practice anyway. The joins between tables should be specified explicitly. In the first query you want the header only, and there is no additional table needed in your example, so you should have just
SELECT *
FROM Orders
WHERE Orders.Order_ID = 12345
whereas in the second query I understand you have a table Parts, which contains descriptions of various parts that can be ordered? If so, then the second query should have:
SELECT *
FROM Order_items
JOIN Parts ON Parts.ID = Order_Items.Part_ID
WHEERE Order_Items.Order_ID = 12345
If in your Orders table you had a field for the ID of the supplier Supplier_ID, pointing to a Suppliers table, and an ID of the person placing the order Customer_ID, pointing to a Customers table, then the first query would look like this:
SELECT *
FROM Orders
JOIN Suppliers ON Suppliers.ID = Orders.Supplier_ID
JOIN Customers ON Customers.ID = Orders.Customer_ID
WHERE Orders.Order_ID = 12345
Hope this is enough for you to learn further on your own :).

error on array retrieved from JOIN query on two tables

hope my title is clear. I am trying to retrieve results from two tables.
So I want everything (hence *) from the table called 'albums'.
and I want only all matching (with album_id) results from table 'contributors'.
$result = mysql_query("SELECT * FROM albums LEFT JOIN contributors ON albums.album_id =
contributors.album_id ORDER BY albums.datum DESC; ") or die(mysql_error());
$aantal_rijen = mysql_num_rows($result);
if ($aantal_rijen > 0) {
for ($i = 0; $i < $aantal_rijen; $i++){
$contributors[] = mysql_result($result, $i, 'contributors');}
but i get a list of similar errors:
contributor not found in MySQL result index ...
Joining of two tables is totally new to my, and maybe it's not the way to go, but maybe it's just a plain simple error in this code, anyway, I'm stuck here,
all help is welcome
thx S
http://php.net/manual/en/function.mysql-result.php
FIELD
The name or offset of the field being retrieved.
It can be the field's offset, the field's name, or the field's table dot field
name (tablename.fieldname). If the column name has
been aliased ('select foo as bar from...'), use the alias instead of
the column name. If undefined, the first field is retrieved.
You're just using the table name contributors, so either you need to specify a single field or limit your select to only the fields you want
$contributors[] = mysql_result($result, $i, 'contributors.name');
OR
$result = mysql_query("
SELECT contributors.*
FROM albums
LEFT JOIN contributors ON albums.album_id = contributors.album_id
ORDER BY albums.datum DESC;
") or die(mysql_error());

A logical problem with two tables

Hey guys, I created a list for fixtures.
$result = mysql_query("SELECT date FROM ".TBL_FIXTURES." WHERE compname = '$comp_name' GROUP BY date");
$i = 1;
$d = "Start";
while ($row = mysql_fetch_assoc($result))
{
$odate = $row['date'];
$date=date("F j Y", $row['date']);
echo "<p>Fixture $i - $d to $date</p>";
}
As you can see from the query, the date is displayed from the fixtures table.
The way my system works is that when a fixture is "played", it is removed from this table. Therefore when the entire round of fixtures are complete, there wont be any dates for that round in this table. They will be in another table.
Is there anyway I can run an other query for dates at the same time, and display only dates from the fixtures table if there isnt a date in the results table?
"SELECT * FROM ".TBL_CONF_RESULTS."
WHERE compid = '$_GET[id]' && type2 = '2' ORDER BY date"
That would be the second query!
EDIT FROM HERE ONWARDS...
Is there anyway I can select the date from two tables and then only use one if there are matches. Then use the rows of dates (GROUPED BY) to populate my query? Is that possible?
It sounds like you want to UNION the two result sets, akin to the following:
SELECT f.date FROM tbl_fixtures f
WHERE f.compname = '$comp_name'
UNION SELECT r.date FROM tbl_conf_results r
WHERE r.compid = '$_GET[id]' AND r.type2 = '2'
GROUP BY date
This should select f.date and add rows from r.date that aren't already in the result set (at least this is the behaviour with T-SQL). Apparently it may not scale well, but there are many blogs on that (search: UNION T-SQL).
From the notes on this page:
//performs the query
$result = mysql_query(...);
$num_rows = mysql_num_rows($result);
//if query result is empty, returns NULL, otherwise,
//returns an array containing the selected fields and their values
if($num_rows == NULL)
{
// Do the other query
}
else
{
// Do your stuff as now
}
WHERE compid = '$_GET[id]' presents an oportunity for SQL Injection.
Are TBL_FIXTURES and TBL_CONF_RESULTS supposed to read $TBL_FIXTURES and $TBL_CONF_RESULTS?
ChrisF has the solution!
One other thing you might think about is whether it is necessary to do a delete and move to another table. A common way to solve this type of challenge is to include a status field for each record, then rather than just querying for "all" you query for all where status = "x". For example, 1 might be "staging", 2 might be "in use", 3 might be "used" or "archived" In your example, rather than deleting the field and "moving" the record to another table (which would also have to happen in the foreach loop, one would assume) you could simply update the status field to the next status.
So, you'd eliminate the need for an additional table, remove one additional database hit per record, and theoretically improve the performance of your application.
Seems like what you want is a UNION query.
$q1 = "SELECT DISTINCT date FROM ".TBL_FIXTURES." WHERE compname = '$comp_name'";
$q2 = "SELECT DISTINCT date FROM ".TBL_CONF_RESULTS.
"WHERE compid = '$_GET[id]' && type2 = '2'";
$q = "($q1) UNION DISTINCT ($q2) ORDER BY date";

Order MySQL results by number of related rows in foreign table

Alright, so I have a table outputting data from a MySQL table in a while loop. Well one of the columns it outputs isn't stored statically in the table, instead it's the sum of how many times it appears in a different MySQL table.
Sorry I'm not sure this is easy to understand. Here's my code:
$query="SELECT * FROM list WHERE added='$addedby' ORDER BY time DESC";
$result=mysql_query($query);
while($row=mysql_fetch_array($result, MYSQL_ASSOC)){
$loghwid = $row['hwid'];
$sql="SELECT * FROM logs WHERE hwid='$loghwid' AND time < now() + interval 1 hour";
$query = mysql_query($sql) OR DIE(mysql_error());
$boots = mysql_num_rows($query);
//Display the table
}
The above is the code displaying the table.
As you can see it's grabbing data from two different MySQL tables. However I want to be able to ORDER BY $boots DESC. But as its a counting of a completely different table, I have no idea of how to go about doing that.
There is a JOIN operation that is intended to... well... join two different table together.
SELECT list.hwid, COUNT(log.hwid) AS boots
FROM list WHERE added='$addedby'
LEFT JOIN log ON list.hwid=log.hwid
GROUP BY list.hwid
ORDER BY boots
I'm not sure if ORDER BY boots in the last line will work like this in MySQL. If it doesn't, just put all but the last line in a subquery.
But the result of the query into an array indexed by $boots.
AKA:
while(..){
$boot = mysql_num_rows($query);
$results[$boot][] = $result_array;
}
ksort($results);
foreach($results as $array)
{
foreach($array as ....)
{
// display table
}
}
You can switch between ksort and krsort to switch the orders, but basically you are making an array that is keyed by the number in $boot, sorting that array by that number, and then traversing each group of records that have a specific $boot value.

Categories