I have the following database table:
AWARD_ID | NOMINEE_ID | VOTER_ID | MULTI_CODE
------------------------------------------------------
5 | 3 | 1 | 9326
5 | 4 | 1 | 9326
5 | 5 | 3 | 8746
I need to display these results in tables grouped by MULTI_CODE, so for example:
So it would look like
<h1>Multi Code: 9326</h1>
<table>
<tr>
<td>Nominee: 3</td><td>Nominee: 4</td>
</tr>
</table>
<h1>Multi Code: 8746</h1>
<table>
<tr>
<td>Nominee: 5</td>
</tr>
</table>
Here is my SQL + PHP so far:
$nomineedetails = mysqli_query($con,"SELECT AWARD_ID, NOMINEE_ID, VOTER_ID, MULTI_CODE
FROM b_awards_votes WHERE AWARD_ID = '5'");
$multi_code = -1;
while($row = mysqli_fetch_array($nomineedetails))
{
$awardID = $row['AWARD_ID'];
$nomineeID = $row['NOMINEE_ID'];
$voterID = $row['VOTER_ID'];
$multiCode = $row['MULTI_CODE'];
print "<h2>$multiCode</h2>";
if ($multi_code != $multiCode) {
print "<table><tr>";
$multi_code = $multiCode;
}
print "<td>Nominee: $nomineeID</td>";";
}
</tr></table>
With this I get this:
8746
9326
Nominee: 3
9326
Nominee: 4 Nominee: 5
Why am I getting the 9326 above the Nominee 3?
First of all, I suggest to order your results by MULTI_CODE to have the correct sorting when looping through the results.
Then, in your loop you always print the headline with the multi code, regardless being different to the previous one.
Please have a look at this code. It isn't tested, so please be aware that there might be errors in it:
$nomineedetails = mysqli_query($con,"SELECT AWARD_ID, NOMINEE_ID, VOTER_ID, MULTI_CODE
FROM b_awards_votes WHERE AWARD_ID = '5' ORDER BY MULTI_CODE ASC");
$multi_code = -1;
while($row = mysqli_fetch_array($nomineedetails))
{
$awardID = $row['AWARD_ID'];
$nomineeID = $row['NOMINEE_ID'];
$voterID = $row['VOTER_ID'];
$multiCode = $row['MULTI_CODE'];
if ($multi_code != $multiCode) {
if($multi_code !== -1) {
print "</table>";
}
print "<h2>$multiCode</h2>";
print "<table>";
$multi_code = $multiCode;
}
print "<tr><td>Nominee: $nomineeID</td></tr>";
}
Related
I have a table as follows that is used to store details of employees:
+---------+---------+------------------+
| of_code | name | employment_status |
+---------+---------+------------------+
| 1 | Jhon | 1 |
| 2 | Ram | 1 |
| 3 | Edward | 3 |
| 4 | William | 2 |
+---------+---------+------------------+
This is one of the options in my Codeigniter project.
Desired output
I want to show the employment_status in separate columns in the view as per the value in it. If employment_status = 1, it should be in the first column. If employment_status = 2, it should be in the second column. If employment_status = 3, it should be in the the column and so on.
Controller (Relevant Part)
$where = NULL;
$this->data['officerList'] = $this->Officer_model->officerSummary($where);
Model
function officerSummary($where){
$q = $this->db->query("SELECT
of_code, name, employment_status as cnt
from tbl_officer $where
");
if ($q->num_rows() > 0) {
return $q->result();
}
}
View (Relevant Part)
<?php
$officerLists = [];
foreach ($officerList as $row) {
if (!in_array($row->cnt, $officerLists)) {
$officerLists[] = $row->cnt;
}
}
?>
<div class="table-responsive" id="datatable">
<table id="ExData" cellpadding="0" cellspacing="0" border="0"
class="table table-bordered table-condensed table-hover table-striped reports-table">
<thead id="th">
<tr class="" style="background-color: #d966ff !important;">
<th>#</th>
<th style width="5%" class="text-center"><font size="1"> Code</th>
<th style width="15%" class="text-left"><font size="1">Name</th>
<th class="text-center" colspan="<?= count($officerLists) ?>"><font size="1">Employment Status</th>
</tr>
</thead>
<tbody>
<?php
$count = [];
if(!empty($officerList)) {
foreach ($officerList as $rows) {
$total += $rows->cnt;
$c++;
?>
<tr>
<td><font size="1"><?= $rows->of_code ?></td>
<td><?= $rows->name ?></td>
<?php
foreach ($officerLists as $value) {
if ($rows->cnt == $value) {
if (isset($count[$value]))
$count[$value] = $count[$value] + $rows->of_code;
else
$count[$value] = $rows->of_code;
echo "<td class='text-center'></td>";
} else
echo "<td class='text-center'>-</td>";
}
}
?>
</tbody>
</table>
The function outs three columns correctly, but with no values. Only '-' shows non-relevant places in the column as follows.
What may be going wrong? Can anyone help?
Maybe using a SELECT - CASE structure can be your option
A query in this way
SELECT of_code,
name,
CASE WHEN employment_status = 1 THEN employment_status AS StatusA,
CASE WHEN employment_status = 2 THEN employment_status AS StatusB,
CASE WHEN employment_status = 3 THEN employment_status AS StatusC
FROM yourTbale;
Every CASE will verify if the status is 1 or 2 or 3
Th previous step will generate a new column with a given alias
Because we need the status value as cell value in our result I put it again after the THEN clause
If this work, you only will need to adapt it in CI sintax
I am a newbie to PHP and I am stuck at a certain point. I tried looking up a solution for it however, I didn't find exactly what I need.
My goal is to create a leaderboard, in which the values are displayed in descending order plus the rank and score are displayed. Furthermore, it should also display whether or not a tie is present.
The database should look like this:
+---------+------+----------------+-------+------+
| user_id | name | email | score | tied |
+---------+------+----------------+-------+------+
| 1 | SB | sb#gmail.com | 1 | 0 |
+---------+------+----------------+-------+------+
| 2 | AS | as#web.de | 2 | 0 |
+---------+------+----------------+-------+------+
| 3 | BR | br#yahoo.com | 5 | 1 |
+---------+------+----------------+-------+------+
| 4 | PJ | pj#gmail.com | 5 | 1 |
+---------+------+----------------+-------+------+
And the outputted table should look something like this:
+------+-------------+-------+------+
| rank | participant | score | tied |
+------+-------------+-------+------+
| 1 | BR | 5 | Yes |
+------+-------------+-------+------+
| 2 | PJ | 5 | Yes |
+------+-------------+-------+------+
| 3 | AS | 2 | No |
+------+-------------+-------+------+
| 4 | SB | 1 | No |
+------+-------------+-------+------+
I managed to display the rank, participant and the score in the right order. However, I can't bring the tied column to work in the way I want it to. It should change the value, whenever two rows (don't) have the same value.
The table is constructed by creating the <table> and the <thead> in usual html but the <tbody> is created by requiring a php file that creates the table content dynamically.
As one can see in the createTable code I tried to solve this problem by comparing the current row to the previous one. However, this approach only ended in me getting a syntax error. My thought on that would be that I cannot use a php variable in a SQL Query, moreover my knowledge doesn't exceed far enough to fix the problem myself. I didn't find a solution for that by researching as well.
My other concern with that approach would be that it doesn't check all values against all values. It only checks one to the previous one, so it doesn't compare the first one with the third one for example.
My question would be how I could accomplish the task with my approach or, if my approach was completely wrong, how I could come to a solution on another route.
index.php
<table class="table table-hover" id="test">
<thead>
<tr>
<th>Rank</th>
<th>Participant</th>
<th>Score</th>
<th>Tied</th>
</tr>
</thead>
<tbody>
<?php
require("./php/createTable.php");
?>
</tbody>
</table>
createTable.php
<?php
// Connection
$conn = new mysqli('localhost', 'root', '', 'ax');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
// Initalizing of variables
$count = 1;
$previous = '';
while($row = mysqli_fetch_array($result)) {
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
?>
<tr>
<td>
<?php
echo $count;
$count++;
?>
</td>
<td><?php echo $row['name'];?></td>
<td><?php echo $row['score'];?></td>
<td>
<?php
if ($row['tied'] == 0) {
echo 'No';
} else{
echo 'Yes';
}
?>
</td>
</tr>
<?php
}
?>
I think the problem is here
$index = $result['user_id'];
it should be
$index = $row['user_id'];
after updating tied you should retrieve it again from database
So I solved my question by myself, by coming up with a different approach.
First of all I deleted this part:
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
and the previous variable.
My new approach saves the whole table in a new array, gets the duplicate values with the array_count_values() method, proceeds to get the keys with the array_keys() method and updates the database via a SQL Query.
This is the code for the changed part:
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
$query = "SELECT * FROM names ORDER BY score DESC";
$sol = $conn->query("$query");
// initalizing of variables
$count = 1;
$data = array();
// inputs table into an array
while($rows = mysqli_fetch_array($sol)) {
$data[$rows['user_id']] = $rows['score'];
}
// -- Tied Column Sort --
// counts duplicates
$cnt_array = array_count_values($data);
// sets true (1) or false (0) in helper-array ($dup)
$dup = array();
foreach($cnt_array as $key=>$val){
if($val == 1){
$dup[$key] = 0;
}
else{
$dup[$key] = 1;
}
}
// gets keys of duplicates (array_keys()) and updates database accordingly ($update query)
foreach($dup as $key => $val){
if ($val == 1) {
$temp = array_keys($data, $key);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=1 WHERE user_id=$v";
$conn->query($update);
}
} else{
$temp = array_keys($data, $k);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=0 WHERE user_id=$v";
$conn->query($update);
}
}
}
Thank you all for answering and helping me get to the solution.
instead of the update code you've got use something simular
$query = "select score, count(*) as c from names group by score having c > 1";
then you will have the scores which have a tie, update the records with these scores and your done. Make sure to set tie to 0 at first for all rows and then run this solution
UPDATE for an even faster solution sql based:
First reset the database:
$update = "UPDATE names SET tied=0";
$conn->query($update);
All records have a tied = 0 value now. Next update all the records which have a tie
$update = "update docs set tied = 1 where score IN (
select score from docs
group by score having count(*) > 1)";
$conn->query($update);
All records with a tie now have tied = 1 as we select all scores which have two or more records and update all the records with those scores.
I have an array of data and want to display it on a table, but the columns that appear in the table according to the number of array data, how to make 12 column array default but the number remains on the database. suppose there are 2 data appear in the table but there are a number of columns 12...?
Models
function get_id($id) {
$this->db->where('my_id', $id);
$get_data = $this->db->get('mytable');
if ($get_data->num_rows() > 0) {
foreach ($get_data->result() as $data) {
$my_result[] = $data;
}
return $my_result;
}
}
Controllers
public function myControllers() {
$id = $this->uri->segment(4);
$data=array('detail' => $this->mymodels->get_id($id));
$this->load->view('layout/wrapper', $data);
}
Views
<table>
<thead>
<tr>
<td>No</td>
<td>ID</td>
<td>Name</td>
<td>Class</td>
</tr>
</thead>
<tbody>
<?php
$no = 1;
foreach ($detail as $row) {
echo '<tr>';
echo '<td>'.$no.'</td>';
echo '<td>'.$row->id.'</td>';
echo '<td>'.$row->name.'</td>';
echo '<td>'.$row->class.'</td>';
echo '</tr>';
$no++;
}
?>
</tbody>
</table>
I expected as this example
NO | ID | NAME | ClASS |
____|____ |______|_______|
1 | 001 | Paul | x |
2 | | | |
3 | | | |
4 | | | |
to 12
If I'm understanding your question, you want to have a default of 12 rows in your table, even if only 2 rows are filled with data.
What about adding a while loop after your foreach loop that continues incrementing your counter and adding rows until your counter reaches 12?
while ($no <= 12) {
echo '<tr>';
echo '<td>'.$no.'</td>';
echo '<td></td>';
echo '<td></td>';
echo '<td></td>';
echo '</tr>';
$no++;
}
my Database table field look like this
id - name - school - subjects - marks
1 - Adam - Highschool - Geography,physics,math - 60,50,40
2- - Jhone - elementry - Math,Language,Geography - 90,20,10
the php file should convert this values into html table using boot strap
my expected reslut to be like this
Hello Jone! this is your results
Math : 90
Language : 20
Geography : 10
I tried different methods like convert the result into array but it did work with me will.
one of them are
<?php
$shop = array( array("title"=>"rose", "price"=>1.25 , "number"=>15),
array("title"=>"daisy", "price"=>0.75 , "number"=>25),
array("title"=>"orchid", "price"=>1.15 , "number"=>7)
);
?>
<?php if (count($shop) > 0): ?>
<table>
<thead>
<tr>
<th><?php echo implode('</th><th>', array_keys(current($shop))); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($shop as $row): array_map('htmlentities', $row); ?>
<tr>
<td><?php echo implode('</td><td>', $row); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
any advice
thanks
It will be great to normalize your data and to avoid any comma separated lists in your database. However you can achieve this very easily using explode():
Input:
mysql> select * from marks;
+----+------+-------------+-------------------------+----------+
| id | name | school | subjects | marks |
+----+------+-------------+-------------------------+----------+
| 1 | Adam | High School | Geography,physics,math | 60,50,40 |
| 2 | Jone | Elementary | Math,Language,Geography | 90,20,10 |
+----+------+-------------+-------------------------+----------+
2 rows in set
PHP code:
<?php
$con = mysqli_connect('localhost','root','','test') or die(mysqli_error($con));
$query = "SELECT * FROM marks";
$result = mysqli_query($con,$query) or die(mysqli_error($con));
if(mysqli_num_rows($result) > 0){
while($row = mysqli_fetch_assoc($result)){
$subject = explode(',',$row['subjects']);
$marks = explode(',',$row['marks']);
echo 'Hello '.$row['name'].'! This is your results:';
echo '<table>';
foreach($subject as $k=>$s){
echo '<tr>
<td>'.$s.'</td>
<td>'.$marks[$k].'</td>
</tr>';
}
echo '</table>';
}
}
?>
Output is table for each user:
Hello Adam! This is your results:
Geography 60
physics 50
math 40
Hello Jone! This is your results:
Math 90
Language 20
Geography 10
For example I have the following MySQL table:
parent_id | child_id
---------------------
1 | 4
1 | 3
1 | 5
2 | 8
3 | 7
I want to print out the parent and all its children in a format like below:
parent | child
---------------------
| 4
1 | 3
| 5
---------------------
2 | 8
---------------------
3 | 7
Basically I just want to display the parent ONCE(Distinct) and list out all its children with PHP. Is it possible to retrieve the above result with just ONE SQL query? I can get the above result if I first query the parents and then recursively query the children using the parent ids but that would be alot more SQL queries hitting the DB.
Or, do I retrieve the result containing every parent_id & children_id and achieve the above result in PHP by using arrays. If so, please tell me how.
Yes. Select normally and use the parents as keys in an array.
//Query normally
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$result[$row["parent_id"]][] = $row["child_id"];
}
Or something similar.
EDIT
The display part would look something like this:
<?php
$result = array(
1 => array(4, 3, 5),
2 => array(8),
3 => array(7)
); //Assuming you get a resultset like this.
$rowIsOpened = false; //Indicates whether a row is currently opened.
//I'm using $rowIsOpened because the row immediately after the rowspanned cell shouldn't be closed.
echo <<<HTML
<table>
<thead>
<tr>
<th>Parent</th>
<th>Children</th>
</tr>
</thead>
<tbody>
HTML;
//Echo a bunch of HTML before actually looping
foreach ($result as $parent => $children) {
echo "<tr>";
echo "<td rowspan=";
echo count($children); //Span over <how many children are> rows
echo ">$parent</td>";
$rowIsOpened = true; //Row is opened
foreach ($children as $child) {
if (!$rowIsOpened) {
echo "<tr>";
} //Only open a row if row is not opened
echo "<td>$child</td>";
echo "</tr>";
$rowIsOpened = false; //Row is now closed. Ready for next iteration.
}
}
//Close the table tags etc.
echo <<<HTML
</tbody>
</table>
HTML;