I'm looking for some help in how best to structure a MySQL query and display the results. I am trying to create a table on a PHP page which has 7 dates across the top and room numbers down the side. In the table, if a person is in a room on the given date then their name appears. I have the following tables:
Table: rooms
Fields: id, room
Table: bookings
Fields: id, name, room, checkin, checkout
The code I currently have is:
<? $start = date('Y-m-d');
$end = date('Y-m-d', strtotime($start." + 6 day")); ?>
<table class="table1">
<thead>
<tr>
<th></th>
<th scope="col"><?= date('d-m', strtotime($start)); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 1 day")); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 2 day")); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 3 day")); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 4 day")); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 5 day")); ?></th>
<th scope="col"><?= date('d-m', strtotime($start." + 6 day")); ?></th>
</tr>
</thead>
<tbody>
<? $q1 = mysqli_query($con,"SELECT * FROM rooms GROUP BY room");
while($row1 = mysqli_fetch_assoc($q1)){ ?>
<tr>
<th><?= $row1['room']; ?></th>
<? $i = 0;
while ($i <= 6) { ?>
<td>
<? $q2 = mysqli_query($con,"SELECT * FROM bookings WHERE ((checkin BETWEEN '$start' and '$end') or (checkout BETWEEN '$start' and '$end') or (checkin <= '$start' AND checkout >= '$end')) and room = '$row1[room]'");
while($row2 = mysqli_fetch_assoc($q2)){
if ($row2['checkout'] > date('Y-m-d', strtotime($start." + ".$i." day")) and $row2['checkin'] <= date('Y-m-d', strtotime($start." + ".$i." day"))) {
echo $row2['name'];
}
} ?>
</td>
<? ++$i;
} ?>
</tr>
<? } ?>
</tbody>
</table>
This code currently produces the result I need however, I'm worried that it's inefficient because of the amount of loops and queries it runs to get the data.
Can anyone suggest a better way of formatting the query/result?
I think the logic you want in the where clause is:
checkin <= '$end' AND checkout >= '$start' and room = '$row1[room]'
A room is occupied between the two dates when the checking is before the end date and the checkout is after the start date.
EDIT:
The clause you have is:
checkin <= '$start' AND checkout >= '$end'
That is different from my solution.
Related
I have a query which select the last entered data into the database month wise and i have assigned it into an array and tried to display it inside a table which works fine but the data is combined togeather as shown below
Example - the first numeric data you see on the table 1245871 should be displayed as follows
Month - 12
Closing Mileage - 45871
But as you can see on the image both the data are combined togeather how can i seperate these two values and display them accordingingly. The code for this is as below,
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$querymain = "SELECT * FROM users";
$resultsmain = mysqli_query($connect,$querymain);
if ($resultsmain->num_rows>0) {
while ($userid = mysqli_fetch_assoc($resultsmain)) {
?>
<table class="table" class="mt-3 mb-3">
<thead class="bg-dark text-light">
<tr>
<th colspan="3"><?php echo $userid['id']; ?></th>
<th colspan="3"><?php echo $userid['name']; ?></th>
<th colspan="3"><?php echo $userid['approved_kmpl'];?> KM</th>
</tr>
</thead>
<thead>
<tr>
<th>Month</th>
<th>Closing Mileage</th>
<th>Usage For Month</th>
<th>Required Per Month</th>
<th>Excess Used</th>
<th>(%)</th>
<th>KM/L</th>
<th>Consumed Liters</th>
<th>Cost</th>
</tr>
</thead>
<tbody>
<?php
$closingmileage = "SELECT extract(MONTH from date) as Month,
MAX(mileage) FROM mileagesnew
WHERE user_id='".$userid['id']."'
AND extract(YEAR FROM date) ='2020'
group by Month
ORDER BY month desc";
$closingres = mysqli_query($connect,$closingmileage);
if ($closingres->num_rows>0) {
while ($closingrow = mysqli_fetch_assoc($closingres)) {
$data =array($closingrow);
foreach($data as $value){
print_r($value);
?>
<tr>
<td> <?php echo implode($value); ?> </td>
</tr>
<tr>
<td> <?php echo implode($value); ?> </td>
</tr>
<?php
}
}
}
else{
echo "No Data Found";
}
?>
</tbody>
</table>
<?php
}
}
You have 2 columns returned in the resultset of the query Month and mileagesnew. So $closingrow will be an array with 2 members, named as the columns names from your table, or the alias you give the column name in the query. So all you need to do is output $closingrow['Month'] and $closingrow['mileagesnew'] seperately in the 2 table cells
Also I assume you want the 2 values on the same row of the tabel to output both cells within the same <tr>...</tr> along with the empty cells you have not filled yet
<?php
$closingmileage = "SELECT extract(MONTH from date) as Month,
MAX(mileage) FROM mileagesnew
WHERE user_id='".$userid['id']."'
AND extract(YEAR FROM date) ='2020'
group by Month
ORDER BY month desc";
$closingres = mysqli_query($connect,$closingmileage);
if ($closingres->num_rows>0) {
while ($closingrow = mysqli_fetch_assoc($closingres)) {
echo "<tr>
<td>$closingrow[Month]}</td>
<td>$closingrow[mileagesnew ]</td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
</tr>";
}
} else{
echo "No Data Found";
}
?>
I'm trying to make a library booking system so when user borrows a book, they will have a due date set 7 days after the issue date (set as CURRENT_TIMESTAMP). However, is there a way for me to just use the CURRENT_TIMESTAMP + 7 days in the php/html code? or do I need to add another table column to set the due date variable in the database?
I have tried to change a variable (fine) in the database which is not needed in my database with the due date. However, this messes up the whole thing which the data wont show.
So currently, I'm trying to add 7 days to the IssueDate variable via DATE_ADD function. However, this won't allow the code to show.
<tr>
<th>#</th>
<th>Book Name</th>
<th>ISBN </th>
<th>Issued Date</th>
<th>Due Date</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
$sid=$_SESSION['stdid'];
$sql="SELECT tblbooks.BookName,tblbooks.ISBNNumber,tblissuedbookdetails.IssuesDate,tblissuedbookdetails.ReturnDate,tblissuedbookdetails.id as rid,tblissuedbookdetails.fine from tblissuedbookdetails join tblstudents on tblstudents.StudentId=tblissuedbookdetails.StudentId join tblbooks on tblbooks.id=tblissuedbookdetails.BookId where tblstudents.StudentId=:sid order by tblissuedbookdetails.id desc";
$query = $dbh -> prepare($sql);
$query-> bindParam(':sid', $sid, PDO::PARAM_STR);
$query->execute();
$results=$query->fetchAll(PDO::FETCH_OBJ);
$cnt=1;
if($query->rowCount() > 0)
{
foreach($results as $result)
{ ?>
<tr class="odd gradeX">
<td class="center"><?php echo htmlentities($cnt);?></td>
<td class="center"><?php echo htmlentities($result->BookName);?></td>
<td class="center"><?php echo htmlentities($result->ISBNNumber);?></td>
<td class="center"><?php echo htmlentities($result->IssuesDate);?></td>
<td class="center"><?php if($result->ReturnDate=="")
{?>
<span style="color:red">
<?php echo htmlentities("Not Return Yet"); ?>
</span>
<?php } else {
echo htmlentities($result->SELECT DATE_ADD(d,7,IssuesDate));
}
?></td>
<td class="center">
<a href="test-return.php?rid=<?php echo htmlentities($result->rid);?>">
<button class="btn btn-primary"><i class="fa fa-edit "></i>Extend</button>
</td>
</tr>
<?php $cnt=$cnt+1;}} ?>
</tbody>
Any "working codes" will not show the results in the "due date" table column and those that are not will just said there's unexpected variable, symbols, etc.
You need to caclculate 7 days in PHP rather than SQL. Use following code in your else block to calculate and display the Due Date.
$datetime = new DateTime( $result->IssuesDate );
$datetime->modify('+7 days');
echo $datetime->format('Y-m-d');
CURRENT_TIMESTAMP + 7 days
The correct syntax in standard SQL is:
CURRENT_TIMESTAMP + INTERVAL 7 DAY
(Your query is valid but does not do what you think it does.)
You possibly want to allow the complete day so you can drop time altogether by using CURRENT_DATE instead of CURRENT_TIMESTAMP:
SELECT CURRENT_DATE AS today, CURRENT_DATE + INTERVAL 7 DAY AS due_date;
+------------+------------+
| today | due_date |
+------------+------------+
| 2019-07-13 | 2019-07-20 |
+------------+------------+
i want make a table than can be input with existing data, and also the table already exist even before the data inputted,table created based on how many days in this month(i.e: right now is october so it have 31 tables since october have 31 days).
The question are i want to put date number in column date and days in column days, basically date =1 so days of week=saturday, date =2 so days of week=sunday(based on current calendar) and so on
i not quite sure about the logic, cause every time i tried, it only fill the first div or its fill the whole divcheck out my code below
CODE
<table class="table table-bordered">
<thead>
<tr>
<th rowspan="2">Action</th>
<th rowspan="2">Date</th>
<th rowspan="2">Day of Week</th>
<th rowspan="2">Location</th>
<th rowspan="2">Brief Description of Activity </th>
<th colspan="6"><center>Project Code & Hour Worked</center> </th>
</tr>
<tr>
<th>A</th>
<th>Hours Worked</th>
<th>B</th>
<th>Hours Worked</th>
<th>C</th>
<th>Hours Worked</th>
</tr>
</thead>
<tbody>
<?php
$start = new DateTime('first day of this month');
$end = new DateTime('first day of this month + 1 month');
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
for($i= 1; $i < date('t') + 1; $i++){
for($j =1;$j<=1;$j++){
echo "<td><a href='#modal-dialog' class='btn btn-xs btn-success' data-toggle='modal'><span class='fa fa-pencil'></span>i=".$i."</td>".PHP_EOL;
}
for($j =2;$j<=2;$j++){
foreach($period as $day){
echo "<td>".$day->format('M-d')."</td>".PHP_EOL;
}
for($j =1;$j<11;$j++){
echo "<td></td>".PHP_EOL;;
}
echo "</tr>";
}
?>
</tbody>
You are doing it wrong. You loop through the days and build the columns. Your loop through the days should build the rows.
<tbody>
<?php
$day = date('Y-m-d',strtotime('first day of this month'));
for($i= 1; $i < date('t') + 1; $i++){
?>
<tr>
<td><a href='#modal-dialog' class='btn btn-xs btn-success' data-toggle='modal'><span class='fa fa-pencil'></span>i=<?php echo $i; ?></td>
<td><?php echo date('M-d',strtotime($day)); ?></td>
<td><?php echo date('l',strtotime($day)); ?></td>
<?php
for($j =1;$j<=8;$j++){
echo "<td></td>".PHP_EOL;
}
?>
</tr>
<?php
$day = date('Y-m-d', strtotime('+1 day', strtotime($date)));
} ?>
</tbody>
My script basically loads data from my database and I have to <br> somewhere but it wont work because its a huge table. So I need to format this table so every 10 rows there is a <br>.
<table align="center" cellspacing="0" cellpadding="0">
<?php
$date = mysql_query("SELECT DISTINCT `date` FROM `matches`");
while($daterow = mysql_fetch_assoc($date)){
echo ' <tr>
<td style="width:60px; background-color:#000000;"><font color="#FFFFFF" style="font-size:11px">'.$daterow['date'].'</font></td>
</tr>
';
$query = mysql_query("SELECT hour, team1, team2, goalsteam1, goalsteam2, competition FROM `matches` WHERE `date`='". $daterow['date'] ."'");
while($row = mysql_fetch_array($query)){
$teamtest = mysql_query("SELECT teamname FROM `teams` WHERE `team`='".$row['team1']."'");
$teamtestrow = mysql_fetch_assoc($teamtest);
$hour = substr($row['hour'],0,5);
echo '
<tr class="teamtable">
<td style="width:60px; font-size:11px;">'.$hour.'</td>
<td style="width:145px; font-size:11px;">'.$teamrow['teamtest'].'</td>
<td style="width:15px; font-size:11px;">'.$row['goalsteam1'].'</td>
<td style="width:15px; font-size:11px;">'.$row['goalsteam2'].'</td>
<td style="width:145px; font-size:11px;">'.$row['team2'].'</td>
<td style="width:120; font-size:11px;">'.$row['competition'].'</td>
</tr>';
}
}
?>
</table>
Or just <br> before every date. When I tried it will just leave a huge blank space up but still no space between the date and matches.
Not too sure if CSS can handle this. And unclear on where you expect a break to occur based on the code you are sharing. But in general you would use the modulus operator in PHP would be a good start. Knowing that maybe this would work for you:
<table align="center" cellspacing="0" cellpadding="0">
<?php
$date = mysql_query("SELECT DISTINCT `date` FROM `matches`");
$counter = 0;
while($daterow = mysql_fetch_assoc($date)){
echo ' <tr>
<td style="width:60px; background-color:#000000;"><font color="#FFFFFF" style="font-size:11px">'.$daterow['date'].'</font></td>
</tr>
';
$query = mysql_query("SELECT hour, team1, team2, goalsteam1, goalsteam2, competition FROM `matches` WHERE `date`='". $daterow['date'] ."'");
while($row = mysql_fetch_array($query)){
$teamtest = mysql_query("SELECT teamname FROM `teams` WHERE `team`='".$row['team1']."'");
$teamtestrow = mysql_fetch_assoc($teamtest);
$hour = substr($row['hour'],0,5);
echo '
<tr class="teamtable">
<td style="width:60px; font-size:11px;">'.$hour.'</td>
<td style="width:145px; font-size:11px;">'.$teamrow['teamtest'].'</td>
<td style="width:15px; font-size:11px;">'.$row['goalsteam1'].'</td>
<td style="width:15px; font-size:11px;">'.$row['goalsteam2'].'</td>
<td style="width:145px; font-size:11px;">'.$row['team2'].'</td>
<td style="width:120; font-size:11px;">'.$row['competition'].'</td>
</tr>';
$counter++;
// Do a modulus check.
if ($counter % 10 == 0) {
echo "<tr><td colspan="6"> </td></tr>";
}
}
}
?>
</table>
The key chunk of code is this:
$counter++;
// Do a modulus check.
if ($counter % 10 == 0) {
echo "<tr><td colspan="6"> </td></tr>";
}
On each loop $counter is incremented by 1. And using the modulus operator in the if() statement we check for every 10th item & then do something. In this case insert a row with an in it.
I am using the following code to generate tables from data from my database. it groups the data by the employee. What I need is to display the totals for the last four columns at the end of each employees table. The Hours, OT, Travel and TOT columns.
Code:
$current_user_name = false;
while($row = mysql_fetch_array($result)) {
// listing a new employee? Output the heading, start the table
if ($row['user_name'] != $current_user_name) {
if ($current_user_name !== false)
echo '</table>'; echo '[divider_padding]';// if we're changing employee, close the table
echo '
<h5>'.$row['last_name'].', '.$row['first_name'].'</h5>[minimal_table]
<table>
<tr>
<th>Date</th>
<th class="tableleft">Description</th>
<th class="tableleft">Job</th>
<th class="tableleft">Activity</th>
<th class="tableleft">Comments</th>
<th class="tableright">Hours</th>
<th class="tableright">OT</th>
<th class="tableright">Travel</th>
<th class="tableright">TOT</th>
</tr>';
$current_user_name = $row['user_name'];
}
// output the row of data
echo '<tr>
<td style="width:75px">'.$row['labor_date'].'</td>
<td class="tableleft">'.$row['description'].'</td>
<td class="tableleft">'.strtoupper($row['job']).'</td>
<td class="tableleft">'.$row['activity'].'</td>
<td class="tableleft">'.$row['comments'].'</td>
<td class="tableright">'.$row['rthours'].'</td>
<td class="tableright">'.$row['othours'].'</td>
<td class="tableright">'.$row['trthours'].'</td>
<td class="tableright">'.$row['tothours'].'</td>
</tr>
';}
echo '</table>[/minimal_table]'; // close the final table
}
?>
I am stuck after trying some tests and can not figure this out.
This is the query gathering the data:
$result = mysql_query("SELECT * FROM data WHERE labor_date BETWEEN '$start' AND '$end' Order by last_name, labor_date ASC");
Any help would be appreciated.
This line is missing an open bracket:
if ($current_user_name !== false)
Should be:
if ($current_user_name !== false) {