Here is my current code:
$varVeh=$_POST['Veh_num'];
$sql_HiScores = "SELECT
c.course_name as course,
e.distance as distance, e.score as score,
e.time as time, e.user as User
FROM hc_entries e
LEFT JOIN hc_course c on e.course=c.course_num
WHERE e.vehicle=$varVeh
ORDER BY course, score DESC";
$result_HiScores = mysql_query($sql_HiScores);
$sql_vehName="SELECT Veh_name FROM hc_vehicle_type WHERE Veh_num=$varVeh ";
$result_vehName = mysql_query($sql_vehName);
$vehName=mysql_fetch_assoc($result_vehName);
echo "<table><tr><th>Best Scores for ".$vehName['Veh_name']."</th></tr></table>";
echo "<table border='1'>";
echo "<tr><th>Course</th><th>Score</th><th>Distance</th><th>Player</th><th>Time</th></tr>";
while($row = mysql_fetch_array($result_HiScores))
{
echo "<tr>";
echo "<td>" .$row['course'] . "</td>";
echo "<td>" .$row['score'] . "</td>";
echo "<td>" .$row['distance'] . "</td>";
echo "<td>" .$row['User'] . "</td>";
}
echo "</table>";
What I think I have to do is create a query that selects * from e.course that builds an array. Then cycle through the existing query with the array results. Finally, I would like to display individual tables for each course and limit it to the top 5 results for each course.
Can anyone confirm or deny my logic, and point me in a direction?
First of all, you shouldn't be using the mysql_ functions, they're deprecated. At the least, you should switch to mysqli_ (a pretty easy switch), or better, learn how to use PDO. It's a bit different and more involved to switch, but your code will be better and safer for it.
With that out of the way: your logic is pretty accurate. Limiting your results to the top 5 results for each course in one query isn't something that's easily done with SQL to my knowledge, so your plan is good: query a list of courses, then cycle through them with your existing query, running it once for each course, with a LIMIT 5 to get the top 5.
You might as well keep the table generation within this loop as well, since it's a table-per-course. You'd want to move the VehName query out of the loop, since you only need to run that once.
Also, some unsolicited PHP advice: any text outside of the tags will just be output directly, so take advantage of its built-in-templating and alternative syntax to make your table generation code nicer:
<?php
/* Gather your data here... */
?>
<table>
<tr><th>Best Scores for <?php echo $vehName['Veh_name'] ?></th></tr>
</table>
<table border='1'>
<tr>
<th>Course</th>
<th>Score</th>
<th>Distance</th>
<th>Player</th>
<th>Time</th>
</tr>
<?php while($row = mysql_fetch_array($result_HiScores)): ?>
<tr>
<td><?php echo $row['course'] ?></td>
<td><?php echo $row['score'] ?></td>";
<td><?php echo $row['distance'] ?></td>";
<td><?php echo $row['User'] ?></td>";
</tr>
<?php endwhile; ?>
</table>
put the entire table html inside the while loop and add 'LIMIT 5' to the end of your query
Related
I have a site where members can mark other members as 'a favourite'. User are able to search the members table in various ways and I want to show from any of the results that are returned whether or not the users returned are favourites of the current user.
This is some very simplified code I have been using to try and get this query to work but I just can't figure it out. Whenever I add 'GROUP BY' to avoid duplicate results from my LEFT JOIN the 'if' statement does not work. The 'if' statment does work however, if I omit the 'GROUP BY' but I get all rows from members table and the favourites table. Thanks.
$result = mysqli_query($db_conx, "SELECT members.*, user_favourites.* FROM members LEFT JOIN user_favourites ON members.id = user_favourites.fav_id GROUP BY members.id");
echo "<table border=''>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>A favourite of User</th>
</tr>";
while($row = mysqli_fetch_array($result)) {
echo "<tr>";
echo "<td>" . $row['firstname'] . "</td>";
echo "<td>" . $row['lname'] . "</td>";
echo "<td>" . $row['email'] . "</td>";
if ($visitor == $userid ){
$msgs = "x";
}
else { $msgs = "0";
}
echo "<td>". $msgs. "</td>";
echo "</tr>";
}
echo "</table>";
mysqli_close($con);
?>
I suggest to you, tu use 2 query's insted one. Simple query is a fast querys. If your site scale up, your query will be slow query and it cause performance problems.
Idea:
For one hand: SELECT FROM members, get all and put it inside array, key=member.id
$members[$row['member_id']]=$row;
On the other hand: SELECT * FROM user_favourites, and put it inside the previous array, refereced by the key fav_id use distinc if you have duplicates.
$members[$row['fav_id']]['favourites']=$row;
Perfect now you have all you need, an array with all information, iterate it.
JilianJ something like this:
<?
//Prepare
$all_users=array()
$query_users='SELECT * from user';
$query_favourites='SELECT * FROM user_favourites';
//Now I find all members information
$users=mysqli_query($db_conx,$query_users);
while($user = mysqli_fetch_array($users)) {
$all_users[$user['id']]=$user;
}
//Now I add favourite information to the users information
$favourites=mysqli_query($db_conx,$query_favourites);
while($favourite = mysqli_fetch_array($favourites)) {
$all_users[$favourite['fav_id']]['fovourite'][]=$favourite['fav_id'];
}
?>
<table>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>A favourite of User</th>
</tr>
<? foreach ($information as $key=>$item) {?>
<tr>
<td><?=$item['firstname'];?></td>
<td><?=$row['lname'];?></td>
<td><?=$row['email'];?></td>
<td>
<? foreach($item['favourites'] as $key2=>$item2) { ?>
<p><?=$all_members[$item2]['name];?></p>
<? } ?>
</td>
</tr>
<? } ?>
</table>
Good luck
I have a pretty good idea of how to do this, but I'm not exactly sure... how to do it , if that makes sense. This is still my first day (going on second without sleep) of learning PHP and I'm trying to complete this project before I call it quits. This is actually all that's left before I can call it quits and be happy with myself. So here's the thing.
I know I've asked quite a few questions today, hopefully this is the last one..
Currently my code pulls information from my database and displays it into a table, like so:
Now, this is great for the feature where I want to list the last 15 transactions, which is what my following code does, please excuse anything that's not done efficiently as it's my first day.
<html>
<table border="1">
<tr>
<th>Transaction Date</th>
<th>Transaction Amount</th>
<th>Item Name</th>
<th>Quantity</th>
</tr>
<?php
require_once 'Config.php';
require_once 'Connection.php';
$totalTransactions = 0;
$totalProfit = 0;
$testquery = "SELECT * FROM $tbl_name WHERE DATE($tbl_name.Date)
BETWEEN DATE_SUB(CURDATE(), INTERVAL 15 DAY) AND CURDATE()";
$results = mysql_query($testquery) or die (mysql_error());
while($row = mysql_fetch_array($results))
{
$totalTransactions += 1;
$totalProfit += $row[$ROW_AMOUNT];
echo "<tr>";
echo "<td align='center'>".$row[$ROW_DATE] . "</td>";
echo "<td align='center'>$". number_format($row[$ROW_AMOUNT], 2) . "</td>";
echo "<td align='center'>null</td>";
echo "<td align='center'>null</td>";
echo "<tr>";
}
echo "<tr>";
echo "<td align='center'><strong>SUM:</strong></td>";
echo "<td align='center'><strong>$".number_format($totalProfit, 2)."</strong></td>";
echo "<td align='center'><strong> </strong></td>";
echo "<td align='center'><strong> </strong></td>";
echo "<tr>";
?>
</table>
</html>
Now, I'm trying to figure out how I can group it like such in a table
[Day] - [Sum]
I understand how to get the sum for the data, obviously because that's what the script above does for the last 15 transactions, but how about grouping them together?
an example of the output I'm looking for is like this (This was done in pure HTML and is just an example of what I'm trying to achieve)
To re-word my question more efficiently, I'm trying to create another table that shows the sum for each date that there is "Transactions" for.
You have to group your columns using the GROUP BY clause and then aggregate the sum of Transaction Amount:
SELECT Date, SUM([Transaction Amount])
FROM $tbl_name
WHERE DATE($tbl_name.Date)
BETWEEN DATE_SUB(CURDATE(), INTERVAL 15 DAY) AND CURDATE()
GROUP BY Date
Please note that you may have to put quotes or something else around the column name Transaction Amount, this is TSQL syntax, I'm not sure how it's done in MySQL.
I'm showing data from Mysql table with php inside HTML table, but i need 2 more things to accomplish to the table:
1- How to Alternate colors for table rows to use 4 different css classes, I am using now class='success' i have 3 more that i want to use and each one should apply to each table row, how to do it? any simple example like a loop or something?
2- Data showing from the oldest record in the table to the latest one, and i want to show the reverse, so the last record shows first in the html table.
My code for this table:
<?php echo "<table class='table'>
<thead>
<tr>
<th>Order#</th>
<th>Name</th>
<th>Total</th>
<th>Submitted On</th>
<th>Status</th>
</tr> </thead>";
while($row = mysqli_fetch_array($result))
{
echo "<tr class='success'>";
echo "<td>" . $row['lite_order_id'] . "</td>";
echo "<td>" . $row['lite_item_name'] . "</td>";
echo "<td>" . $row['lite_email'] . "</td>";
echo "<td>" . $row['lite_country'] . "</td>";
echo "<td>" . $row['lite_order_total'] . "</td>";
echo "</tr>"; }
echo "</table>"; ?>
1 - Use id attribute to style individual elements. Check it out here
2 - In your MySQL query, use ORDER BY:
(I presume you have an id column here)
$query = "SELECT * FROM `yourtable` ORDER BY `id` ASC";
See here
To get reverse records you can use mysql ORDER BY clause or PHP function array_reverse()
I am using the following query to populate a table:
$result = mysql_query("SELECT vendor, part_number, machine, Sum(q_received) AS received, Sum(q_rejected) AS rejected FROM qa_parts Group by vendor, part_number, machine Order by vendor ASC");
I want to group the results by the Vendor then under the vendor display all the parts that have come from them and their details.
This is what I need it to do:
http://www.gen-techno.com/images/old.jpg
What it is doing now:
http://www.gen-techno.com/images/new.jpg
As you can see the the parts for Vendor O.P.S Products are not being grouped under that vendor like the parts are in the above example for Allied Electronics.
My table code as of now:
while($row = mysql_fetch_array($result))
{
echo "<h4>" . $row['vendor'] . "</h4>[fancy_table]<table>
<tr>
<th>Part Number</th>
<th>Quantity Received</th>
<th>Quantity Rejected</th>
<th>Machine</th>
</tr>";
echo "<tr>";
echo "<td>" . $row['part_number'] . "</td>";
echo "<td>" . $row['received'] . "</td>";
echo "<td>" . $row['rejected'] . "</td>";
echo "<td>" . $row['machine'] . "</td>";
echo "</tr>";
echo "</table>[/fancy_table]";}
During each loop you have to decide if it is time to draw the heading--you're going to list a new vendor. If it isn't a new vendor, you're still listing parts for the one you drew the last heading for, so you don't want the heading or to end the table.
$current_vendor = false;
while($row = mysql_fetch_array($result)) {
// listing a new vendor? Output the heading, start the table
if ($row['vendor'] != $current_vendor) {
if ($current_vendor !== false)
echo '</table>[/fancy_table]'; // if we're changing vendors, close the table
echo '
<h4>'.$row['vendor'].'</h4>[fancy_table]
<table>
<tr>
<th>Part Number</th>
<th>Quantity Received</th>
<th>Quantity Rejected</th>
<th>Machine</th>
</tr>
';
$current_vendor = $row['vendor'];
}
// output the row of data
echo '<tr>
<td>'.$row['part_number'].'</td>
<td>'.$row['received'].'</td>
<td>'.$row['rejected'].'</td>
<td>'.$row['machine'].'</td>
</tr>
';
}
echo '</table>[/fancy_table]'; // close the final table
On another note, you should start updating this code to use PDO. Obviously, you're in the middle of updating something that used to exist... make PDO a part of this update. The mysql_* functions are on the way to deprecation, and soon they'll be gone.
PDO is not hard to transition into, and it is MUCH easier now while you're already working on things than it will be later, when you're faced with the "it isn't broke, don't fix it" problem.
Here's a quick look at your code using the superior PDO DBA method:
$pdo = new PDO("mysql:host=localhost;dbname=database", '-username-', '-password-');
$sql = '
SELECT
vendor,
part_number,
machine,
SUM(q_received) AS "received",
SUM(q_rejected) AS "rejected"
FROM
qa_parts
GROUP BY
vendor,
part_number,
machine
ORDER BY
vendor ASC
';
$statement = $pdo->prepare($sql);
$statement->execute();
while ($order = $statement->fetch()) {
/* Put your table code here! */
}
Documentation
foreach - http://php.net/manual/en/control-structures.foreach.php
mysql_query (DEPRECATED) - http://php.net/manual/en/function.mysql-query.php
PDO - http://www.php.net/manual/en/book.pdo.php
PDO::prepare - http://www.php.net/manual/en/pdo.prepare.php
PDOStatement::fetch - http://www.php.net/manual/en/pdostatement.fetch.php
PDOStatement::execute - http://www.php.net/manual/en/pdostatement.execute.php
You need to split your loop into two parts. First part checks if you've got a new/different vendor, and sets up the "outer" setup. Then the inner part which dumps out that vendor's parts.
e.g.
$prev_vendor = null;
while($row = ...) {
if ($row['vendor'] != $prev_vendor) {
... new vendor stuff ...
$prev_vendor = $row['vendor']; // update vendor for next iteration
}
... dump this row's machine data ...
}
PHP 7.1.7
I'm really new to PHP and having troubling thinking through this or finding a good example.
For the code below, I'm simply making a table of query results. What I need to do is loop through the query for each unique UID to create a bullet list in table form. So, the table output is a UID in COLUMN 1 and then COLUMN 2 of the table contains a new row for each LOG_TEXT (and where the UID would only be echo'd on the first pass of the loop).
Example:
User24: •Opened Door 1
•Opened Door 2
•Opened Door 5
•Opened Door 6
User33: •Opened Door 1
•Opened Door 2
•Opened Door 5
•Opened Door 6
<?php include 'db_connect.php'; ?>
<?php
$result = mysqli_query($con,"
SELECT uid, log_text
FROM logs l
WHERE (l.log_date BETWEEN '2017-07-01' AND '2017-07-31')
");
echo "<table class='table_standard_grey_with_border' >
<tr>
<th>UID</th>
<th>LOG TEXT</th></tr>";
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
echo "<td>" . $row['uid'] . "</td>";
echo "<td>" . $row['log_text'] . "</td>";
}
echo "</tr></table>";
mysqli_close($con);
?>
Order your query-result by userId, so all actions by the same user are 'grouped' together.
$result = mysqli_query($con,"
SELECT uid, log_text
FROM logs l
WHERE (l.log_date BETWEEN '2017-07-01' AND '2017-07-31')
ORDER BY uid
");
And within your PHP, just keep track of the previously printed userId and print an empty cell if it is equal to the previous one:
$previousUid = null;
while($row = mysqli_fetch_array($result))
{
echo "<tr>";
if ($previousUid === $row['uid']) {
echo "<td></td>"; // Empty cell
} else {
echo "<td>" . $row['uid'] . "</td>";
$previousUid = $row['uid'];
}
echo "<td>" . $row['log_text'] . "</td>";
echo "</tr>";
}
Another possible way to do this is to fetch the data from the query into a multidimensional array before displaying it.
$result = mysqli_query($con,"
SELECT uid, log_text
FROM logs l
WHERE (l.log_date BETWEEN '2017-07-01' AND '2017-07-31')
");
while($row = mysqli_fetch_array($result)) {
$data[$row['uid']][] = $row['log_text'];
}
mysqli_close($con);
This will give you an array of data that can be displayed in an HTML view more simply, so that your data access code can be separated from your presentation code. This grouping will work whether or not you include an ORDER BY clause in your query, but you probably should do so anyway to be sure the data displays in the order you expect it to. It looks like ORDER BY uid, log_date would make sense for this data.
<table class='table_standard_grey_with_border'>
<tr>
<th>UID</th>
<th>LOG TEXT</th>
</tr>
<?php foreach ($data as $uid => $log_texts): ?>
<tr>
<td><?= $uid ?></td>
<td>
<ul>
<?php foreach ($log_texts as $log_text): ?>
<li><?= $log_text ?></li>
<?php endforeach ?>
</ul>
</td>
</tr>
<?php endforeach ?>
</table>
A disadvantage to this approach is that it will be a little slower than displaying each row as you fetch it, and will consume more memory.