From the image above, I am trying to generate this table dynamically with PHP. Below is my tables in the mysql DB
Here is the SQL that I am using to pull the data from the database
SELECT DISTINCT execution_date,class_name,method_name,status FROM test_cases INNER JOIN test_case_executions ON test_cases.id=test_case_executions.test_case_id WHERE version='$platform' AND execution_date >= ( CURDATE() - INTERVAL 2 DAY ) ORDER BY execution_date DESC;
This is returning the data that need but I am struggling to figure out how to build the table. I was thinking of using arrays and when I have all the data I need, then echo out the table code. The thing I need to guard is that a test is not always guaranteed that there will be three dates for a test. Thanks for the help in advance.
You will have to do a couple passes on your data set to generate that output. That is, you'll have lets say 4 rows representing all of the status values and you will have to iterate over it a couple of times to extract out the date column headers and the "Class" row identifiers.
You can perform this in PHP. So on the 1st pass you grab the dates for the header. And also store the "Class" for the first column.
On the 2nd pass you then iterate over the data again but this time its wrapped in a loop so you can pull out the records for that cell.
Here is some psuedo-code:
$records = $db->query("select * from your_query here...");
$dates = [];
$classes = [];
// first pass is to pull out the distinct dates & classes which represent our bounds
foreach($records AS $record) {
$dates[] = $record['execution_date'];
$classes[] = $record['class_name'];
}
// distinct the date set and sort them from lowest to highest
$dates = array_unique($dates);
$dates = sort($dates);
$classes = array_unique($classes);
// display the date row
echo "<tr><td> </td>"
foreach($dates AS $date) {
echo $date;
}
echo "</tr>";
// start displaying each class+date pair
foreach($classes AS $klass) {
echo "<tr>";
echo "<td>" . $klass . "</td>";
// display each date record for this class
foreach($dates AS $date) {
$class_and_date_record = filter($records, $klass, $date);
if($class_and_date_record) {
echo "<td>" . $class_and_date_record['status'] . "</td>";
}
}
echo "</tr>";
}
function filter($records, $klass, $date) {
foreach($records AS $row) {
if($row['class_name'] == $klass && $row['execution_date'] == $date) {
return $row;
}
}
return NULL;
}
If I understand your question correctly, you only want to output data to the table when there is a value in "execution_date"
$query = "SELECT DISTINCT execution_date,class_name,method_name,status FROM test_cases INNER JOIN test_case_executions ON test_cases.id=test_case_executions.test_case_id WHERE version='$platform' AND execution_date >= ( CURDATE() - INTERVAL 2 DAY ) ORDER BY execution_date DESC;";
if ($result = $mysqli->query($query)) {
/* fetch associative array */
while ($row = $result->fetch_assoc()) {
echo '<table>';
if(isset($result["execution_date") && !empty($result["execution_date"])){
echo '<tr><td>' . $result["execution_date"] . '</td></tr>';
...
}
echo '</table>';
}
/* free result set */
$result->free();
}
The line to note is :
if(isset($result["execution_date") && !empty($result["execution_date"])){
will check your returned row for execution_date having a value.
You can then print the rest of the items using the same $result["<column name>"] formatting.
Related
I know there are other questions/answers about this sort of thing, but it took me a while to figure this specifically out, so I figured I'd share it with the community, as likely there are others who could benefit.
I had put together code like the following, which worked fine, but if you needed to add a column, meant adding the name 4 times before you even got to adding it where you wanted in the table:
<?php
// Prepare statement & retreive data from database
$sql_retreive = $con->prepare("
SELECT widget_id
, widget_name
, widget_price
, widget_upc
, widget_color
FROM widgets
WHERE widget_price > ?
");
$bind_process = $sql_retreive->bind_param('d',$price);
$sql_retreive->execute();
$result = $sql_retreive->get_result();
// Initiate arrays to place variables from query in order to transpose data from database
$widget_id = [];
$widget_name = [];
$widget_price = [];
$widget_upc = [];
$widget_color = [];
// If there are results, fetch values for each row and add values to each corresponding array
if($result->num_rows > 0 ){
while($row=$result->fetch_assoc()){
$widget_id[] = $row['widget_id'];
$widget_name[] = $row['widget_name'];
$widget_price[] = $row['widget_price'];
$widget_upc[] = $row['widget_upc'];
$widget_color[] = $row['widget_color'];
} // end of while
} // end of if num_rows > 0
// Build dynamic table with results transposed
echo "<table class='table'><thead>";
echo "<tr><th>Widgets</th>"; for ($i=0; $i<count($crop_name);$i++) {echo "<th>".$widget_name[$i]." (".$widget_id[$i].")</th>";}
echo "</tr></thead><tbody>";
echo "<tr><td>widget_price</td>"; for ($i=0; $i<count($widget_price);$i++) {echo "<td>".$widget_price[$i]."</td>";} echo "</tr>";
echo "<tr><td>widget_upc</td>"; for ($i=0; $i<count($widget_upc);$i++) {echo "<td>".$widget_upc[$i]."</td>";} echo "</tr>";
echo "<tr><td>widget_color</td>"; for ($i=0; $i<count($widget_color);$i++) {echo "<td>".$widget_color[$i]."</td>";} echo "</tr>";
echo "</tbody></table>";
?>
So I wanted to figure out a better way... see my answer below...
After spending a while working on it, I came up with this:
<?php
// Prepare statement & retreive data from database
$sql_retreive = $con->prepare("SELECT widget_id, widget_name, widget_price, widget_upc, widget_color FROM widgets WHERE widget_price > ?");
$bind_process = $sql_retreive->bind_param('d',$price);
$sql_retreive->execute();
$result = $sql_retreive->get_result();
if($result->num_rows > 0 ){ // If there are results, fetch values for each row and add values to each corresponding array
// Initiate an array for each field specified, in which to place variables from query, in order to transpose data from database
for($i = 0; $i < mysqli_num_fields($result); $i++) { // loop through fields
$field_info = mysqli_fetch_field($result); // for each, retreive the field info
$column = $field_info->name; // retreive the field name from the field info
$$column = []; // note double $$, create a blank array using the field name, will loop through for each
} // end of for loop
while($row=$result->fetch_assoc()){ // for each row of responses, place the data into the above created arrays
$field_info = mysqli_fetch_fields($result); // retreive the field info
foreach ($field_info as $field_value) { // for each, retreive the field info
$column = $field_value->name; // retreive the field name from the field info
$$column[] = $row[$column]; // note double $$, using the array (which uses the field name), place the row data in, and loop through for each
} // end of foreach loop
} // end of while
} // end of if num_rows > 0
// Build dynamic table with results transposed
echo "<table class='table'><thead>";
echo "<tr><th>Widgets</th>"; for ($i=0; $i<count($crop_name);$i++) {echo "<th>".$widget_name[$i]." (".$widget_id[$i].")</th>";}
echo "</tr></thead><tbody>";
echo "<tr><td>widget_price</td>"; for ($i=0; $i<count($widget_price);$i++) {echo "<td>".$widget_price[$i]."</td>";} echo "</tr>";
echo "<tr><td>widget_upc</td>"; for ($i=0; $i<count($widget_upc);$i++) {echo "<td>".$widget_upc[$i]."</td>";} echo "</tr>";
echo "<tr><td>widget_color</td>"; for ($i=0; $i<count($widget_color);$i++) {echo "<td>".$widget_color[$i]."</td>";} echo "</tr>";
echo "</tbody></table>";
?>
This enables you to just add the column/field name into the query, and then use the values where you want in the table.
Please upvote if you find this helpful!
Hi I would like to compare two tables from two different databases.
Select from the first database
$sql= mysqli_query ("SELECT * FROM emasa.staff_detail");
$row = mysqli_fetch_array($sql);
Select from the second database
$sql2 = mysqli_query ("SELECT * FROM employee");
$row2 = mysqli_fetch_array($sql2);
Then I compare the two table
if ($row['icnum'] == $row2['emp_ic'])
{
echo "Data already exist in both database.";
}
else
{
while ($row = mysqli_fetch_assoc($sql))
{
echo "<td align='center' height='30'>" . $row ['name'] . "</td>";
echo "<td align='center'>" .$row['icnum'] . "</td>";
}
}
But my problem is it only compares the first row in the database.
My output should only display the staff name that is not available in the other database. However, this is my output.
Based on the output it only compares the first row. So how do I change my code so that it compares the whole row. Please help me, thank you!
You're not looping through the results of the query. You're simply getting back the first row and going with that.
Ex:
$sql= mysqli_query ("SELECT * FROM emasa.staff_detail");
This is returning a result set which you then need to use
$row = mysqli_fetch_array($sql);
to get the actual values. The problem comes when
$row = mysqli_fetch_array($sql);
by itself only gives you one row.
Solution 1
You must use code like this:
while($row = mysqli_fetch_array($sql))
{
//Do some comparison
}
Since you're going to have to loop through two different result sets, you're going to have to do a loop within a loop, build an array of results and then loop through the results afterwards to output your HTML.
Ex:
while($row = mysqli_fetch_array($sql))
{
while($row2 = mysqli_fetch_array($sql2))
{
if ($row['icnum'] == $row2['emp_ic'])
{
//add to array of equal data
}
else
{
//add to array of not equal data
}
}
}
foreach($array as $not_equal_or_equal_data)
{
//output your desired HTML
}
Solution 2
Depending on what you actually care about, you could do a sql statement like this
$sql = "
SELECT
*
FROM
emasa.staff_detail AS sd
JOIN db2.employee AS e
ON sd.icnum = e.emp_ic";
This would return all the rows where those two columns were equal
I am trying to run a query off multiple array variables and display the results in a table.
The user selects 1 or more records, which includes BOL and CONTAINER. These selections are put in their own arrays and they are always an equal amount.
<?php
$bolArray = explode(',', $_POST['BOL']);
$containerArray = explode(',', $_POST['CONTAINER']);
$count = count($bolArray); // to get the total amount in the arrays
I use a FOR loop to separate each value from the 2 arrays:
for($i = 0; $i < $count; $i++)
{
$bol = $bolArray[$i];
$container = $containerArray[$i];
}
Here is the part where I'm stuck and probably where I am messing up.
I need to take each variable from the FOR loop and run query using both variables.
First, I'll start the table:
echo "<table><thead><tr><th>BOL</th><th>Container</th></thead><tbody>";
Here is where I tried a FOREACH loop:
foreach($containerArray as $container) // I am not sure if I am using this FOREACH correctly
{
And now, the query. Please take note of the variables from the first FOR loop:
$preQuery = "SELECT * FROM mainTable WHERE CONTAINER = '".$container."' AND BOL = '".$bol."'";
$preRes = mysql_query($preQuery) or die(mysql_error());
$preNum = mysql_num_rows($preRes);
I use a WHILE loop with a mysql_fetch_assoc:
while($preRow = mysql_fetch_assoc($preRes))
{
echo '<tr>'
echo '<td>'.$preRow[BOL_NUMBER].'</td>';
echo '<td>'.$preRow[CONTAINER_NUMBER].'</td>';
echo '<td>'.$preRow[ANOTHER_COLUMN].'</td>';
echo '</tr>'
}
}
echo '</tbody></table>';
?>
The query actually works. Problem is, it only returns 1 record, and it's always the last record. The user could select 4 records, but only the last record is returned in the table.
I tried to use the same query and paste it inside the first FOR loop. I echoed out the query and it displayed the same amount of times as the number of array values, but will only return data for the last record.
I do not understand what I am doing wrong. I just want to display data for each value from the array.
Edit
Here is what the code looks like when I throw the query in the first FOR loop:
echo "<table class='table table-bordered'><thead><tr><th>BOL</th><th>Container</th></tr></thead><tbody>";
for($i = 0; $i < $count; $i++)
{
$bol = $bolArray[$i];
$container = $containerArray[$i];
$preQuery = "SELECT BOL_NUMBER, CONTAINER_NUMBER FROM `intermodal_main_view` WHERE BOL_NUMBER = '". $bol ."' AND CONTAINER_NUMBER = '".$container."'";
$preRes = mysql_query($preQuery) or die();
$preNum = mysql_num_rows($preRes);
while($preRow = mysql_fetch_assoc($preRes))
{
echo '<tr>';
echo '<td>'.$preRow[BOL_NUMBER].'</td>';
echo '<td>'.$preRow[CONTAINER_NUMBER].'</td>';
echo '</tr>';
}
}
echo "</tbody></table>";
I think you can use "IN" if your POST vars are comma separated.
$preQuery = "
SELECT * FROM mainTable
WHERE CONTAINER IN ($_POST['CONTAINER'])
AND BOL IN ($_POST['BOL'])
";
$preRes = mysql_query($preQuery) or die(mysql_error());
$preNum = mysql_num_rows($preRes);
Then go to your while loop....
This would omit the need for creating an array and looping it.
Also, you need to switch to PDO for your query, and switch to parameter binding. It will take all of an hour to learn.
I have a table with the rows but for some reason it populates only 14 rows. I have around 800 rows in the db. Any ideas?
code:
$result = mysqli_query($con,"SELECT * FROM translation ORDER BY id");
while($row = mysqli_fetch_row($result) and $property = mysqli_fetch_field($result))
{
echo "<tr>";
foreach($row as $column => $value) {
// $column is column name 'englsih', 'spanish' etc.
$name = $property->name;
echo "<td align='left' class='cell".$column."'>". $value . "</td>";
}
echo "<td><span class='edit_b'></span><span class='remove_b'></span></td></tr>";
}
echo "</thead></table>";
I assume your translation table has 14 columns?
The problem is this:
... and $property = mysqli_fetch_field($result) )
You are fetching information about the columns in your result-set - and not even using it - and as soon as you have passed the last column, this will return false and your loop will end.
Don't fetch information about the columns in the same loop as your main results loop.
I'm querying the database first to get all records associated with a certain userid, then i need to go in and modify the array, because one of the fields is an id and i need the name associated with that id.
So i use columnCount to iterate through the resulting array at the index of the id and replace it with the right name, which works fine, for the first six results. columnCount only returns 6, but those first six are renamed as they should be. But outside of that it takes the results from that pdostatement and populates the table normally, with all the relevant data, 17 rows right now.
Why is it returning 6, or what am i doing to get that wrong columncount?
global $__CMS_CONN__;
$timeqry = 'SELECT facility_id, program, date, visit_length, mileage, served FROM timesheet_db WHERE volunteer_id = '.$_SESSION['user_id'];
$stmt = $__CMS_CONN__->prepare($timeqry);
$stmt->execute();
$columns = $stmt->columnCount();
print $columns;
if($stmt)
{
$arrValues = $stmt->fetchAll(PDO::FETCH_ASSOC);
for($x=0;$x<$stmt->columnCount();$x++)
{
global $__CMS_CONN__;
$qry = 'SELECT facility FROM facility_db WHERE id = '.$arrValues[$x]['facility_id'];
$stmt1 = $__CMS_CONN__->prepare($qry);
$stmt1->execute();
if($stmt1)
{
$facilityName = $stmt1->fetchAll(PDO::FETCH_ASSOC);
foreach ($facilityName as $item)
{
foreach ($item as $key => $val)
{
$arrValues[$x]['facility_id'] = $val;
}
}
}
}
print "<table style=\"font-size:90%\">\n";
print "<tr>\n";
print "<th style=\"width:100%\">Facility</th>";
print "<th>Program</th>";
print "<th>Date</th>";
print "<th>Visit Length</th>";
print "<th>Mileage</th>";
print "<th>Served</th>";
print "</tr>";
foreach ($arrValues as $row)
{
print "<tr>";
foreach ($row as $key => $val)
{
print "<td>$val</td>";
}
print "</tr>\n";
}
print "</table>\n";
}
You asked for six columns in your first SELECT query:
SELECT facility_id, program, date, visit_length, mileage, served FROM timesheet_db WHERE volunteer_id = $_SESSION['user_id']
So, naturally, columnCount() is 6. It doesn't multiply the column count by the number of rows returned or anything like that.
If you want the number of rows, you need count($arrValues) (the manual says database behavior with rowCount() is inconsistent regarding SELECTs).