I have two databases. The first contains a list of upload doucuments and who they are for when uploaded and expiry date. This is stored as numbers representing each grade of person using implode. so column name 'foagrade' has 10,11,12 in row one. The second database is a list of grades and there ID's eg 10 = manager, 11 = HR etc. I am using left join and a basic html table to display a query.
$result = mysqli_query($con,
"SELECT UPLOAD.id, UPLOAD.title, UPLOAD.faoGrade,UPLOAD.faoLocation, UPLOAD.date, UPLOAD.expiry, GRADE.ID, GRADE.GRADE as GR, GRADE.id
FROM UPLOAD
LEFT JOIN GRADE ON
UPLOAD.faoGrade=GRADE.ID
where owner=$user");
echo "<table id='previous'>
<tr>
<th>Title/Document name:</th>
<th>For attention of Grade</th>
<th>For Location</th>
<th>date</th>
<th>Date expires</th>
<th>Delete this briefing</th>
</tr>";
while($row = mysqli_fetch_array($result))
{
$id=$row['id'];
echo "<tr>";
echo "<td>" . $row['title'] . "</td>";
echo "<td>" . $row['GR'] . "</td>";
echo "<td>" . $row['foaLocation']."</td>";
echo "<td>" . date("D, d M Y ",($row['date']));
echo "<td>" . date("D, d M Y ",($row['expiry']));
echo "<td>delete</td> ";
echo "</tr>";
}
echo "</table>";
The query shows all the details but only shows the first grade stored in the column faograde (MANAGER) not 11 or 12.
How would I explode or split this? So for each number in this column a grade name is shown. i will also have to do the same for column 'faoLocation', but working on one issue at a time.
These tables should be normalized, but with what you have already you can do something like this:
SELECT UPLOAD.id as uploadID,
UPLOAD.title,
UPLOAD.faoLocation,
UPLOAD.date,
UPLOAD.expiry,
GRADE.ID as gradeID1,
GRADE.GRADE as GR,
GRADE.id as gradeID2 FROM UPLOAD, GRADE
WHERE
FIND_IN_SET(gradeID2,UPLOAD.faoGrade)
and UPLOAD.owner=$user;
Update
Here's the SQL Fiddle.
It is a bit confusing that there are multiple columns called id & ID. It's best to give them intuitive names like grade_ID or user_ID. From a normalization standpoint you could be using a relational table instead of the comma separated column (depending on how this data enters the database). Here's a video about normalization.
Related
Hello and thanks for your time!
I'm trying to pull data from a mysql table using PHP, and am fairly new to both mysql and php.
I have a table built on racing information, where the following race results are recorded:
Date, Type, WL1, L1, L2, etc up to L15
WL1 column contains a value from L1 to L15, and stands for "winning lane 1" - basically what lane the car was in that came in first place.
Columns L1 to L15 contain racers' names.
Given the above, I'm trying to display the following in a table:
Date, Type, WL1 and the value of L1 through L15 as "Winner" when the data in columns L1 through L15 match the entry in column WL1.
Example:
-----------------------------------------
Date | Type | WL1| Winner
-----------------------------------------
May 5 | Rally | 13 | John
May 7 | Stock | 2 | Stewart
May 15 | Touring | 7 | Eddy
I'm able to achieve results like this using the following code:
$sql = "SELECT * FROM races";
if($result = mysqli_query($conn, $sql)){
if(mysqli_num_rows($result) > 0){
echo "<table>";
echo "<tr>";
echo "<th>Date</th>";
echo "<th>Type</th>";
echo "<th>WL1</th>";
echo "<th>Winner</th>";
echo "</tr>";
while($row = mysqli_fetch_array($result)){
echo "<tr>";
echo "<td>" . $row['Date'] . "</td>";
echo "<td>" . $row['Type'] . "</td>";
echo "<td>" . $row['WL1'] . "</td>";
if($row['WL1'] == 'L1'){
echo "<td>" . $row['L1'] . "</td>";
}elseif($row['WL1'] == 'L2'){
echo "<td>" . $row['L2'] . "</td>";
That being said, I'm thinking there has to be an easier way than iterating through 15 values with if/elseif statements. I've tried both "while" and "for" loops with incremental values, but I only get empty results or errors, most likely due to my inexperience. I've also reproduced the above using a complex CASE statement in MySQL, but again, I'm trying to reduce lines of code.
If someone could suggest a more concise method of pulling this data, either through a MySQL statement or PHP code, I'd appreciate it. Even better if you can point to some good online examples/tutorials - the whole "teach a man to fish" thing...
Your data structure is what is causing your problem; you should really have a table that links racers and lanes for each race and then JOIN to that. Having said that, you can simplify your existing code by noting that the value in $row['WL1'] is the column name of the winner, so you can simply replace your if structure with:
echo "<td>" . $row[$row['WL1']] . "</td>";
I've created a sample data structure here with races, lanes and racers tables. To query from this structure you would do something like:
SELECT DATE_FORMAT(r.Date, '%b %e') AS Date, r.Type, r.Winner AS WL1, rs.Name AS Winner
FROM races r
JOIN lanes l ON l.Race = r.id AND l.Lane = r.Winner
JOIN racers rs ON rs.id = l.Racer
Which for my sample data gives:
Date Type WL1 Winner
May 5 Rally 13 John
May 7 Stock 2 Stewart
May 15 Touring 7 Eddy
I am having an unexpected ton of difficulty trying to return all the currencies that a store accepts from the currency(banking) table.
The results I want should be:
Store name: Test
Store type: Grocery Store
Currency accepted: Bitcoin, Euros, Dollars
The results I get (when I remove GROUPBY Store) are:
Store name: Test
Store type: Grocery Store
Currency accepted: Bitcoin
Store name: Test
Store type: Grocery Store
Currency accepted: Euros
Store name: Test
Store type: Grocery Store
Currency accepted: Dollars
When I remove groupby store, then I only get the first result above (just the bitcoin result for currency)
There are 3 rows for the store id for currency, but it is only returning the first row's value (Bitcoin) since I am using GROUPBY and only one one result for the Test Store (But all 3 currencies for that store). I can't seem to get it to pull all 3 matching rows for the store id in that table into my results so that I get the 3 currencies returned.
I know the query is good from other tests, but I just don't know how to adjust the code below so that all currencies are returned and listed for the "Currency Accepted" table row on the page.
Here is the relevant code:
$query = "(
SELECT * FROM store
LEFT JOIN store_banking SB ON store.id=SB.store_id
LEFT JOIN banking B ON SB.banking_id = B.id
LEFT JOIN store_gaming SG ON store.id=SG.store_id
LEFT JOIN gaming G ON SG.gaming_id = G.id
WHERE
('$type' IS NULL OR '$type' = '' OR G.type = '$type')
And
('$currency' IS NULL OR '$currency' = '' OR B.currency= '$currency')
GROUP BY store.name
Order by store.name
)";
$result = mysqli_query($link, $query);
echo "<table border='1' cellpadding='5' cellspacing='5'>
<tr>
<th>Store Name</th>
<th>Type</th>
<th>Currency Accepted:</th> //need this to show all 3 matches; only showing 1
</tr>";
/* fetch associative array */
while ($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
echo "<td>" . $row['name'] . "</td>";
echo "<td>" . $row['type'] . "</td>";
echo "<td>" . $row['currency'] . "</td>"; //only returns first results row :(
echo "</tr>";
}
/* free result set */
mysqli_free_result($result);
echo "</table>";
mysqli_close($link);
?>
I think a GROUP_CONCAT might do the trick for you.
And when you select with GROUP_CONCAT it's often best to set an alias on the select to easier reference it later.
For example:
SELECT GROUP_CONCAT(currency) as currency
I have three tables:
Campaign
Customer
Office
As in the Campaign table the customer_id the same is as ID in the Customer table,
then he must show the customer_name also in Customer table.
Now he is showing the customer id with: $row->customer_id
I now have the following
if ($result = $mysqli->query("SELECT * FROM campaign ORDER BY campaign_id"))
{
// display records if there are records to display
if ($result->num_rows > 0)
{
// display records in a table
echo "<table>";
while ($row = $result->fetch_object())
{
// set up a row for each record
echo "<tr>";
echo "<td>" . $row->campaign_name . "</td>";
echo "<td>" . $row->customer_id . "</td>";
echo "<td>" . $row->office_id . "</td>";
echo "</tr>";
}
echo "</table>";
}
}
Thanks!
It's not incredibly clear what you're asking, but maybe try this query?
SELECT c.*, cust.* FROM campaign c, customer cust WHERE c.customer_id=cust.customer_id ORDER BY c.campaign_id
Using explicit (instead of implicit) JOINs, this query can be written as this:
SELECT c.*, cust.* FROM campaign c JOIN customers cust ON c.customer_id=cust.customer_id
As a note, I usually prefer to call out column names explicitly in queries, but since you didn't post your schema, I wasn't sure the names of your columns. Possibly something like this:
SELECT c.campaign_name, cust.customer_id FROM campaign c JOIN customers cust ON c.customer_id=cust.customer_id
Hi I want to create Categories listed which are saved in my database so when user upload his images and he select the category it saves the data in database in Cat column
Now I want to show category in PHP like this
Categories Total
Animals (4)
Celebrations (2)
Locations And Travel (11)
Object or still life (1)
Transportation (9)
Here is my PHP I am succeeded to show Categories names but not total category in each category
<?php
$con=mysqli_connect("localhost","root","123","user");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"Select Cat from save_data Group By Cat ")
or die(mysql_error());
echo "<table border='1'>
<tr>
<th>Categories</th>
<th>Total</th>
</tr>";
while($row = mysqli_fetch_array($result, MYSQL_ASSOC))
{
echo "<tr>";
echo "<td>" . $row['Cat'] . "</td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
Extend the table cell:
<td colspan="2"></td>
This way it extends over another cell.
Also I notice you are mixing mysqli and mysql:
or die(mysql_error());
Try to use mysqli as objects and \Exceptions instead of errors. It's worth learning about :-)
Update:
I did not understand your question at first. Please provide your schema so we can see your table structure.
Usually you would have 2 tables, one with categories and one with data and join them with a GROUP BY (if an item can be in several categories, you would have a third table like category_has_item!):
SELECT c.category AS cat,
COUNT(i.items) AS num
FROM category c
LEFT JOIN items i
ON c.category_id = i.category_id
GROUP BY c.category
Use LEFT JOIN to display empty categories and JOIN (without LEFT) to avoid empty categories.
Change your table echo:
echo "<td>" . $row['cat'] . "</td><td>(" . $row['num'] . ")</td>";
Update:
If you only have 1 table, I strongly suggest you to read about database normalization.
Update your query:
Select Cat,COUNT(Data) AS num from save_data Group By Cat
Replace Data by your data column
and your echo line:
echo "<td>" . $row['Cat'] . "</td><td>(" . $row['num'] . ")</td>";
try to change your sql query like this
SELECT count(*) AS total_count FROM (SELECT Cat FROM save_data GROUP BY Cat HAVING COUNT(Cat) > 1) AS t
I've try a lot of ways to get this table print as good as it should but I failed.
I know it's simple thing so I hope you help me with it.
Here's my code:
<?php
include('../connect.php');
$id=$_SESSION['login_user'];
$sql = "Select CourseName , Studentname from course p natural join student t";
$rs_result = mysql_query ($sql, $connection);
echo "<center>";
echo "<table>";
echo "<tr> <th>Course Name</th> <th> Students Name</th> </tr>";
// loop through results of database query, displaying them in the table
while($row = mysql_fetch_array( $rs_result )) {
// echo out the contents of each row into a table
echo "<tr>";
echo '<td>' . $row['CourseName'] . '</td>';
echo "<td rowspan=''> $row[Studentname] </td> ";
echo "</tr>";
}
echo "</table>";
echo "</center>";
?>
I want to be something like this
Course | Name | Student name |
Math101 | john, Mike |
...
Also, is the JOIN query between the two tables CORRECT or not?
The two tables are:
Course ( Course name - Course id )
Student ( Student name - Course id )
Try this query
$sql ="SELECT cor.CourseName,GROUP_CONCAT(stu.StudentName) AS StudentName
FROM course AS cor
LEFT JOIN student AS stu
ON stu.CourseId = cor.CourseId";
And change the the line in below
echo "<td rowspan=''>" . $row['Studentname'] . "</td> ";
This line:
echo "<td rowspan=''> $row[Studentname] </td> ";
You are accessing the array element improperly. Studentname should have single quotes around it like such:
echo "<td rowspan=''>" . $row['Studentname'] . "</td> ";
Also, in your query, this may work better:
$sql = "SELECT c.CourseName, s.StudentName
FROM course AS c
INNER JOIN student AS s
ON s.CourseId = c.CourseId";
Please use below format
SELECT CourseName , Studentname
FROM course
INNER JOIN student
ON course.id = student.id
Thanks
The problem is with Your rowspan attribute - You need to provide it with the exact number of rows to span through. Anyway, I think it is the collspan attribute You want to use, so e.g.
echo "<td collspan='2'> {$row['Studentname']} </td> ";
which means it will span through 2 columns, thus stundet's name will be both under the Name and Student name columns.
Is this what You were expecting?
Also I highly recommend not to use mysql_ functions but learn how to use mysqli or at least PDO.
I'm under the impression that you wanted to display a comma-separated list of names of all the students that attend each course, for each separate CourseName. In this case, you could change your SQL query to something like this:
SELECT CourseName, GROUP_CONCAT(Studentname SEPARATOR ', ') as names
FROM Course p NATURAL JOIN Student t
GROUP BY CourseName;
Hello please take a look of this answer. Dynamic rowspan while fetching records from database
I think it might be helpfull.