I have a PHP/MySQL query that returns the following:
array ( 'name' => 'Jess', 'month' => '2020-03-31 12:28:00', 'count' => '1', )
array ( 'name' => 'Bob', 'month' => '2020-04-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Tom', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
array ( 'name' => 'Bob', 'month' => '2020-05-31 12:28:00', 'count' => '2', )
The months return in an ordered fashion (E.g. January records are always before February records).
However, not every user will have a result every month (see above).
And I want my data to present such as this, in an html table:
Month Jess Bob Tom
March 1
April 2
May 2 2
Here is my (non working) attempt:
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
$name = $row["customer_name"];
print("<b>".$name." </b><br>");
$total = 0;
$cur_month = NULL;
$namepos = array();
$th = "<th>Month</th>";
$tr = "";
$npcount = 0;
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
//Assign variables from mysql results
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//Only add the month once!
if($cur_month != $month){
$cur_month = $month;
$tr .= "</tr><tr><td>" . $cur_month. "</td>";
//print($cur_month . "<br>");
}
//store the username 'position' to build a table (this determines how many spaces are needed.)
if(!array_key_exists($name,$namepos))
{
$namepos[$name] = $npcount;
$npcount += 1;
$th .= "<th>" .$name . "</th>";
}
//add details to tr in correct pos
for( $i = 0; $i < $namepos[$name]; $i++){
$tr .= "<td></td>";
}
$tr .= "<td> ".$count." </td>";
//print(" ".$name . " " . $count . " <br>");
}
print("<table border='1'><tr>". $th . "</tr>" . $tr . "</table>");
print("<br>Total: ".$total." <br><br> ");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Which unfortunately results in results such as this:-
What would be the best way to achieve this?
I have tried storing the position of each user in the table headers, but then it is difficult to know how many empty columns to add before and the entry (see image above).
just a quick update. I have managed to get what I desired through the following code
<?php
/*loop through all customers and print out each induvidual users performance*/
$con = mysqli_connect("localhost","root","","perfmon");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
exit();
}
//main query for customer names
if ($customers = mysqli_query($con, "SELECT Distinct(customer_name) FROM slog ORDER BY customer_name DESC;")) {
while($row=mysqli_fetch_assoc($customers))
{
//Name of customer
$name = $row["customer_name"];
//Print customer name
print("<b>".$name." </b><br>");
//Used to display total jobs
$total = 0;
$user_list = array("Month");
$monthlist = array();
$st_array = array();
//Loop over the customer names, and pull the modified count per user.
if ($user_perf = mysqli_query($con, "select modified_by as name, created_date as month, count(modified_by) as count from slog where customer_name = '$name' group by modified_by, MONTH(created_date) order by month;")) {
while($row=mysqli_fetch_assoc($user_perf))
{
$month = date("F",strtotime($row["month"]));
$name = $row["name"];
$count = $row["count"];
$total += $row["count"];
//make our left column (months)
if(!in_array($month, $monthlist)){
array_push($monthlist, $month);
}
//Collect all unqiue users, to make our headers array. also stores the order theyre in.
if(!in_array($name, $user_list)){
array_push($user_list, $name);
}
//make a 2d array of all data
$tmp = [$month, $name, $count];
array_push($st_array, $tmp);
}
/**Process fetched data **/
$row = "";
$previous_pos = 1;
$fe = True;
//Print each unique user as a table header
print("<table border='1'>");
print("<tr>");
foreach ($user_list as $th){
print("<th>".$th."</th>");
}
print("</tr>");
//Loop the month array
foreach ($monthlist as $td){
//Loop the user array
foreach ($user_list as $usr){
//Loop our "2d" array (an array containing Month,User,Count)
foreach($st_array as $array_2d){
//If we match the correct month and user, return the count value. This ensures the users return in the correct order.
if ($array_2d[0] == $td && $array_2d[1] == $usr){
//Pos - Get the current position of the selected user.
//Establish how many empty entries need to come before. E.g. User in col 1 has no empty entries infront. User in column2 has 1 entry empty infront (if column 1 is empty).
$pos = array_search($usr, $user_list);
if ($previous_pos != $pos){
$row .= str_repeat("<td>0</td>", ($pos-$previous_pos-1));
}
//Assign our previous position
$previous_pos = $pos;
//If our first entry isn't in column 1, add an extra 0.
if($pos!==1 && $fe)
$row .= "<td>0</td>";
$fe = False;
//Add the data
$row .= "<td>".($array_2d[2])."</td>"; //change to [1] for debug
}
}
}
//Print the table row.
print("<tr><td>".$td ."</td>" . $row ."</tr>");
//Reset our variables.
$row = "";
$fe=True;
$previous_pos = 1;
$first_result = True;
}
print("</table></br>");
mysqli_free_result($user_perf);
}
}
mysqli_free_result($customers);
}
mysqli_close($con);
?>
Essentially I created 3 arrays. An array of users, an array of months, and an array of all data (3d array). I use the months and users to record the order in which the tables should be presented. I then loop through my 3d array and print the relevant data.
Despite the downvotes, I would like to thank you all for offering your help. If you have any recommendations please let me know.
Related
How to assign value to an array in while loop in php from mysqli result to make a counter to filter another while loop??
I want to assign something like this for my counter variable:
$counter = array("6:00 Am" => 0, "8:00 Am" => 0, "10:00 Am" => 0);
For this code:
//This is from transaction table
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($res2);
while($rows5 = $res2->fetch_assoc())
{
//Not working
$counter[] = array($rows5['tr_sched'] => 0)
}
So I can filter this another while loop if the schedule time is greater than to my limit variable, like this:
//This is from my schedule table
$stm = "SELECT sc_time FROM schedule GROUP BY sc_time";
$res = $conn->query($stm);
$counter = array();
while($row4 = $res4->fetch_assoc())
{
//Note working
if($counter[$row4['sc_time']] >= $limit/*=10*/)
{
echo "<option disabled="">" . $row4['sc_time'] . "</option>";
}
else
{
echo "<option>" . $row4['sc_time'] . "</option>";
}
}
The goal of all the codes above is to display all schedule time from schedule table as an option for select element and if the schedule time is already have a 10 records or greater than(limit variable) on my transaction table for today it will display as option but disable so it can't be selected by user.
I hope you get what I mean, I will try to keep active to answer if you have something to clarify about my question.
You don't need the while loop at all.
You can use array functions to populate the array with static values.
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($stm2);
// get values from a single column
$keys = array_column($res2->fetch_all(MYSQLI_ASSOC), 'tr_sched');
// create an array with all values as 0 and keys from $keys
$counter = array_fill_keys($keys, 0);
Of course, don't reset the array later on with $counter = array();
If you want to loop anyway, then you can use a simple foreach loop.
$stm2 = "SELECT tr_sched FROM transaction WHERE tr_date = CURRENT_DATE()";
$res2 = $conn->query($stm2);
foreach($res2 as $rows5) {
$counter[$rows5['tr_sched']] = 0;
}
I ask in connection to this article:
How to get the columns names along with resultset in php/mysql?
$selecttable = mysql_query("SELECT * FROM $tablename WHERE (preis_bis <= '$price_upper' AND preis_bis > '$price_lower') LIMIT 1");
for ($i = 0; $i < mysql_num_fields($selecttable); $i++) {
$field_info = mysql_fetch_field($selecttable, $i);
// not WORKING
while($rowvalue = mysql_fetch_row($selecttable)) {
echo "<tr><td>Price: ".$rowvalue[$i]."</td></tr>";
}
echo "<tr><td style='border:1px solid #c0c0c0;padding:10px;'><!-- {$field_info->name} -->";
// get Logo and provider name
$select_getlogo = mysql_query("SELECT * FROM rrv_anbieter WHERE aid = '$field_info->name' LIMIT 1");
while($row_logo = mysql_fetch_object($select_getlogo)){
echo $row_logo->name.'<br><img src="images/'.$row_logo->logo.'" style="max-width: 200px;">';
}
#while($rowvalues2 = mysql_fetch_row($selecttable)) {
# foreach($rowvalues2 as $_column) {
# echo "<td>{$_column}</td>";
# }
#}
echo "</td></tr>";
}
I do not get it to get the correct row value within the "for" loop. Writing col names is working, but showing additionally the right value in same loop not.
Can someone help?
You need to iterate once more in the inner loop to get all rows of the table's columns.
while($rowvalue = mysql_fetch_row($selecttable)) {
foreach($rowvalue as $r){
echo "<tr><td> ".$r."</td></tr>";
}
}
$rowvalue[$i] showed rows incorrectly because it's following index based on the outer loop which is $i.
So basically the loop will print all rows of each column for n-times where n=number of all columns, not just the price column.
.
And you can also print all elements per-$rowvalue at once with :
while($rowvalue = mysql_fetch_row($selecttable)) {
$allElements = implode(",",$rowvalue ); // comma ',' is the separator
echo "<tr><td>". $allElements."</td></tr>";
}
}
I have an array of Information States And Totals. I want to see how to get the Total of all the Totals for each state.
I know I have to use a loop but I am not sure which - what would I do?
This is what I have so far. It's making the array from a database.
$WorkFind = mysql_query(
"SELECT Customers.State, WorkOrders.Total
FROM WorkOrders
INNER JOIN Customers
ON WorkOrders.CID=Customers.ID
WHERE WorkOrders.Type <> 'Warranty'
AND (WorkOrders.Status <> 'Closed'
OR WorkOrders.Status <> 'Cancelled')
AND WorkOrders.TransferID='0'
ORDER BY Customers.State ASC");
while ($Work = mysql_fetch_array($WorkFind)) {
}
The while loop has made the array but I'm unsure what to put into it.
I'm using PHP 5.3 and MYSQL 5.2
Try this:
$WorkFind = mysql_query("SELECT Customers.State AS State, WorkOrders.Total AS Total -- ...");
$total = array();
while ($Work = mysql_fetch_array($WorkFind)) {
$state = $Work['State'];
if (!isset($total[$state])) {
$total[$state] = 0;
}
$total[$state] += $Work['Total'];
}
// format as simple table
echo '<table><tr><th>State</th><th>Total</th></tr>';
foreach ($total as $state_name => $state_total) {
echo '<tr><td>' . $state_name . '</td><td>' . $state_total . '</td></tr>';
}
echo '</table>';
My code does the two columns, like this:
neighborhood 1
restaurant 1
neighborhood 1
restaurant 2
neighborhood 1
restaurant 3
I WANT:
neighborhood 1
restaurant 1
restaurant 2
restaurant 3
$result = mysql_query("SELECT ID,RName,NHood FROM Restaurants ORDER BY NHood ASC, TRIM(LEADING 'The ' FROM RName) ASC",$connect);
$numRows = mysql_num_rows($result);
$middleIndex = (int)(($numRows+1) / 2);
$names = array();
while($row = mysql_fetch_assoc($result)) {
$names[] = $row['RName'];
$id[] = $row['ID'];
$hood[] = $row['NHood'];
}
// print the left column
echo "<table>";
echo "<tr>";
echo "<td width=60%>";
echo "<div id=\"left\">\n";
for($i = 0; $i < $middleIndex; $i++) {
echo $hood[$i];
echo "<p>$names[$i]</p>\n";
}
echo "</div>\n";
echo "</td>";
// print the right column
echo "<td>";
echo "<div id=\"right\">\n";
for($i = $middleIndex; $i < $numRows; $i++) {
echo $hood[$i];
echo "<p>$names[$i]</p>\n";
}
echo "</div>\n";
echo "</tr>";
echo "</table>";
Here's the logic you want (pseduocode):
SELECT
ID,
RName,
NHood
FROM
Restaurants
ORDER BY
NHood ASC, RName ASC
This should return a list of results ordered first by the neighborhood, then by restaurant name.
Next, you'll process those results line-by-line to create a nested array with the data structure you want for your view:
$neighborhoods = array();
foreach($result as $row)
{
// Add each restaurant to a list named for the current neighborhood
$neighborhoods[$row['NHood']][] = $row['RName'];
}
This will produce a data structure like this:
$neighborhoods = array(
'neighborhood1' => array(
'restaurant1',
'restaurant2',
'restaurant3',
),
'neighborhood2' => array(
'restaurant1',
'restaurant2',
),
)
Which you will then use by doing this:
foreach($neighborhoods as $neighborhood => $restaurants)
{
echo $neighborhood;
foreach($restaurants as $restaurant)
{
echo $restaurant;
}
}
If your list is really large and you're worried about memory the implementation is a bit different but the logic is the same. This technique is faster but it's a bit harder to read and maintain because presentation and data layer logic are all mixed together:
$currentNH = null;
while($row = fetch_row($results))
{
// Detect when the neighborhood changes
if($currentNH != $row['NHood']) {
echo $row['NHood'];
}
echo $row['RName'];
}
I have the next:
$students=array('student1','student2','student3','student4');
$date=array('date1','date2','date3');
$students represents the files and $date represents the columns.
For each $student and $date there is a value different.
For example:
$students['student1']$dates['date1']='value11';
$students['student1']$dates['date2']='value12';
$students['student1']$dates['date3']='value13';
$students['student2']$dates['date1']='value21';
....
.....
etc.
date1 date2 date3
student1 value11 value12 value13
student2 value21 value22 value23
student3 value31 value32 value33
I want fill the values in a table.
I want to load these values in a grid dynamically.
The count for $students and $dates change dynamically.
These values filled in a table I need to insert into database.
I need to update the values into database.
My table in database has the follow fields:
id_tabla estudiante date values
1 estudiante1 date1 value11
2 estudiante1 date2 value12
3 estudiante1 date3 value13
4 estudiante2 date1 value21
5 estudiante2 date2 value22
6 estudiante2 date3 value23
can you help me? Thanks.
The $students is genertated by a query in database.
$dates is generated by a range of the dates in php.
The idea is to do a form with text input $students x $dates where the datas should be included. With this form I should get the values datas.
You have quite a lot of requirements and without knowing the context it's not trivial to choose the right data structure. From your example I guess that you have an array with students and an array with dates. The size of the arrays can change, but you always need to attach the dates-array to each student, right?
So based on my assumption, I think you don't need to rearrange the two arrays into one. You can do your enlisted tasks with the given structure.
Outputting each student with dates in a table:
<table>
<?php foreach($students as $student) { ?>
<tr>
<td><?php echo $student; ?></td>
<?php foreach($dates as $date) { ?>
<td><?php echo $date; ?></td>
<?php } ?>
</tr>
<?php } ?>
</table>
Inserting in a database:
<?php
$insert_dates = "'" . implode("','", $dates) . "'";
foreach($students as $student) {
$qry = "INSERT INTO `students` (`name`, `date1`, `date2`, `date3`)
VALUES ('" . $student . "', " . $insert_dates . ")";
//execute query
}
Updating:
<?php
$qry = "UPDATE `students`
SET date1='".$dates[0]."', date2='".$dates[1]."', date2='".$dates[2]."'
WHERE name IN ('" . implode("','", $students) . "')";
//execute query
BUT this approach has some obvious flaws concerning the dynamic changes. So if you are going to work with databases, you should build associative arrays with the keys corresponding to the column names of the table:
$students=array();
$students[] = array('name' => 'student1');
$students[] = array('name' => 'student2');
$students[] = array('name' => 'student3');
$students[] = array('name' => 'student4');
$dates=array();
$dates[] = array('date1'=>'15/04/20', 'date2'=>'20/05/15', 'date3'=>'18/11/10');
The dynamic update query would then look like so:
$set_data = '';
foreach($dates as $key => $value) {
$set_data .= $key . "='".$value."',";
}
$set_data = substr($set_data, 0, -1); //remove last comma
$qry = "UPDATE `students`
SET " . $set_data . "
WHERE name IN ('" . implode("','", $students) . "')";
//execute query
There's a whole lot more you can achieve by playing with data structures (e.g., applying and changing the dates for each student individually, choosing the student-name as the key of the associative array so you can access each student by name, etc.). So at first you should figure out what you need the data for and then choose an appropriate structure based on that. I think you get the idea and I hope it helps!
//UPDATE
Based on your updated question, I think this could be a good approach for the structure (although I still don't know where the data comes from and how/if you can populate that array dynamically/programatically):
$students = array();
$students[] = array(
'name' => 'student1',
'dates' => array(
'date1' => 'code123kil',
'date2' => 'dadfdre145',
)
);
$students[] = array(
'name' => 'student2',
'dates' => array(
'date1' => 'daytetyeyy',
'date2' => 'dafdfe335',
'date3' => 'code123kil'
)
);
//and so on
So now, let's output it into a grid:
<table>
<?php foreach($students as $student) { ?>
<tr>
<td>Name: <?php echo $student['name']; ?></td>
<td>Dates: <?php echo implode(', ', $student['dates']); ?></td>
</tr>
<?php } ?>
</table>
Insert into a table:
<?php
foreach($students as $student) {
foreach($student['dates'] as $key => $value) {
$qry = "INSERT INTO `your_table` (`estudiante`, `date`, `values`)
VALUES ('".$student['name']."','".$key."','".$value."')";
//execute query
}
}
Update the date-values in a table for a given student
<?php
//find the given student in the array
$student_to_update = 'student2';
$student_info = null;
foreach($sudents as $student) {
if($student['name'] == $student_to_update) {
$student_info = $student;
break;
}
}
//update the student in database:
if(!is_null($student_info))
foreach($student_info['dates'] as $key => $value) {
$qry = "UPDATE `your_table`
SET `values`='".$value."'
WHERE `estudiante` = '".$student_info['name']."'
AND `date`='".$key."'";
//execute query
}
}
Update the date-values in a table for each student
<?php
foreach($students as $student) {
foreach($student['dates'] as $key => $value) {
$qry = "UPDATE `your_table`
SET `values`='".$value."'
WHERE `estudiante` = '".$student['name']."'
AND `date`='".$key."'";
//execute query
}
}
Does this help:
$students=array('student1','student2','student3','student4');
$date=array('date1','date2','date3');
$c = 0;
$countArr = count($students);
$newArr = array();
for($c = 0; $c < $countArr; $c++) {
$x = 0;
foreach($date as $val) {
$newArr[$c]["date".($x+ 1)] = $date[$x];
$x++;
}
}
echo "<pre>";
print_r($newArr);