Creating a table of dates from a database - php

Before I begin I'm not asking for a solution - as I'm trying to learn I'm just looking for some pointers so I can work it out myself.
I'm currently learning php and mysql, and have been given the task of creating a resource booking table and form. A form places a name, resource, start and end date into a database, and then this needs to be extracted and displayed as a table on a web page, so users can see if there is a meeting already booked at their desired time.
Final product mockup:
Here is the database table I made in phpmyadmin (called "meetings"):
I've written a while loop to loop through hours (from 8:00 to 19:00). This works left to right not up and down, so when checking if a meeting is already booked I'll have to search for 8:00 monday, then 8:00 tuesday etc:
$i = 8;
while($i < 20)
{
echo "<tr>".
"<td>".$i.":00</td>".
"<td></td>".
"<td></td>".
"<td></td>".
"<td></td>".
"<td></td>".
"<td></td>".
"</tr>";
$i++;
}
and I've started a function "isMeeting" but I have no idea where to go from here
function isMeeting()
{
$query= "SELECT * FROM meetings"; //WHERE hour part of start datetime field is $hour?
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array( $result )) {
}
}
What would be my next steps to populating the table?

Related

Grouping database entries into dynamic HTML tables

I have a database where teams will have multiple entries each with different locations. Each entry will have a team name. So for example, team1 might appear several times but each time the location will be different.
The structure of the DB is (each of these represents a column header):
team_name, first_name, last_name, location, arrival_time
My current working code creates HTML tables grouped by team name but currently only creates one row to show the first location and the time of arrival for the first location. I need this to dynamically create more rows to show all locations and arrival times for each team.
The desired result would look like this -
https://codepen.io/TheBigFolorn/pen/LqJeXr
But current result looks like this -
https://codepen.io/TheBigFolorn/pen/qgMppx
And here is an example of how the DB table might look -
https://codepen.io/TheBigFolorn/pen/daqJze
I've tried breaking up the echo and adding a second while loop before the row that I want to apply the above logic to but it seems to break everything. Any input on how I get this to work without having to use separate queries for each team would be very much appreciated. I'm new to php so please go easy on me :)
<?php
$leaders = "SELECT *, COUNT(location) FROM my_example_table GROUP BY team_name";
$result = mysqli_query($connect, $leaders) or die ("<br>** Error in database table <b>".mysqli_error($connect)."</b> **<br>$sql");
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo "
<div class='red-border'>
<h2>". $row["team_name"]. "<br><small>Total locations visited: ". $row["COUNT(location)"]. "</small></h2>
</div>
<div class='data-holder'>
<table>
<tr>
<th>Location</th>
<th>Time of arrival</th>
</tr>
<tr><td>". $row["location"]. "</td> <td>". $row["arrival_time"]. "</td></tr>
</table>
</div>
";
}
} else {
echo "0 results";
}
?>
Your problem is due to the GROUP BY, as you've probably realised. This is necessary in order to get a count per team, but causes the number of rows output to be only 1 per team - that's what grouping does. Fundamentally, running an aggregate query such as a COUNT or SUM is incompatible with also outputting all of the row data at the same time. You either do one or the other.
Now, you could run two queries - one to get the counts, and one to get all the rows. But actually you don't really need to. If you just select all the rows, then the count-per-team is implicit in your data. Since you're going to need to loop through them all anyway to output them in the HTML, you might as well use that process to keep track of how many rows you've got per team as you go along, and create the "Total number of locations" headings in your HTML based on that.
Two things are key to this:
1) Making the query output the data in a useful order:
SELECT * FROM my_example_table Order By team_name, arrival_time;
2) Not immediately echoing HTML to the page as soon as you get to a table row. Instead, put HTML snippets into variables which you can populate at different times in the process (since you won't know the total locations per team until you've looped all the rows for that team), and then string them all together at a later point to get the final output:
$leaders = "SELECT * FROM my_example_table Order By team_name, arrival_time;";
$result = mysqli_query($connect, $leaders) or die ("<br>** Error in database table <b>".mysqli_error($connect)."</b> **<br>$sql");
$currentTeam = "";
$locationCount = 0;
$html = "";
$teamHtmlStart = "";
$teamHtmlEnd = "";
if ($result->num_rows > 0)
{
while($row = $result->fetch_assoc())
{
//run this bit if we've detected a new team
if ($currentTeam != $row["team_name"]) {
//finalise the previous team's html and append it to the main output
if ($currentTeam != "") $html .= $teamHtmlStart.$locationCount.$teamHtmlEnd."</table></div>";
//reset all the team-specific variables
$currentTeam = $row["team_name"];
$teamHtmlStart = "<div class='red-border'><h2>".$currentTeam."<br><small>Total locations visited: ";
$locationCount = 0;
$teamHtmlEnd = "</small></h2>
</div>
<div class='data-holder'>
<table>
<tr>
<th>Location</th>
<th>Time of arrival</th>
</tr>";
}
$teamHtmlEnd .= "<tr><td>". $row["location"]. "</td> <td>". $row["arrival_time"]. "</td></tr>";
$locationCount++;
}
//for the final team (since the loop won't go back to the start):
$html .= $teamHtmlStart.$locationCount.$teamHtmlEnd."</table></div>";
echo $html;
}
else {
echo "0 results";
}
Here's a runnable demo (using some static data in place of the SQL query): http://sandbox.onlinephpfunctions.com/code/2f52c1d7ec242f674eaca5619cc7b9325295c0d4

PHP, looping through query results in SQL

I'm currently having trouble trying to create a loop for my desired outcome.
I'm currently creating a student record card which stores numerous data of different students (fake students).
I have created a query which returns the relevant data I need (see picture one, phpmyadmin)
SELECT mods.mid, mtitle, credits, enrl.ayr
FROM stud, smod, mods, enrl
WHERE stud.sid = '154279' AND stud.sid = smod.sid
AND smod.mid = mods.mid AND stud.sid = enrl.sid
ORDER BY `enrl`.`ayr` DESC
As you can see by the results, there are attributes:
mid
mtitle
credits
ayr
I have ordered by ayr in decending order. I am trying to make a loop that will run through the return on this query and print out each row until the end of whatever the current year is. Almost grouping all rows with the same year e.g. '2001/02' into a sub table which I can then name and print.
As you can see by my second picture of the student records page, I need to be able to print all records for the one year, then create a new header for the next existing year and print all containing rows for that.
{EDIT}
PHP Code:
$query = "SELECT mods.mid, mtitle, credits, enrl.ayr
FROM stud, smod, mods, enrl
WHERE stud.sid = '154279' AND stud.sid = smod.sid AND smod.mid = mods.mid AND stud.sid = enrl.sid
ORDER BY enrl.ayr DESC
";
$scap = '';
$curYear = $row['ayr'];
if($result = $link->query($query)) {
while ($row = $result->fetch_assoc() && $row['ayr'] == $curYear) {
$scap .= "<table id=\"test\" style=\"width:100%\">
<tr>
<td> " . $row['mid'] . " </td> <td> " . $row['mtitle'] . "</td> <td> " . $row['credits'] . " <td> " . $row['ayr'] . "</td>
</tr>
</table>";
}$result->free();
}
Thanks in advance.
Let's say you commit to one query max for the whole page. Like I said in comments
I would have a variable, call it $curYear. Start it out as some junk
string. In your loop, if the cur year thing is different than
$curYear, create a new segment in your output but regardless update
$curYear variable
That was not meant to interfere with your existing source code (that much). It is just a sentinel to alert you to a year change (year/term whatever).
So it starts as some junk value, like "797fsdf*"
Now inside your while, remember, you have ALL the years coming in from that result set for all years.
Do what I said in that pink block above comparing that variable $curYear to
$row['ayr']
When those two values are different, time to do whatever HTML treatment you want (creating a new html table, a new div, who cares). Let's call this the separation thing.
Regardless, after you output the row, make sure you have set $curYear to $row['ayr']. Why is that important? Because the next loop you want to know if you need to do the separation thing.
The tricky part is if you are doing html tables, you have to close out the previous table (prior year) if you are not on your first year

Check if time in a database surpasses specific hour

I'm making a calendar using PHP and have run into some issues:
I want the calendar to be more automated at the moment as I'm manually creating the table and putting the times and days in myself, which is fine, but my issue is that I'd need a SQL function for every single hour (from 10:00-17:00) for every single day which seems extremely inefficient.
My HTML table code is structured as such:
<tr>
<td>
<span>
<p style="float:left">10:00</p>
<p style="float:right"> (<?php echo $var->monday_10; ?>)</p>
</span>
</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
And I have this PHP function:
public function get_CalendarCount($conn)
{
// TODO: Comment this function
// TODO: If a booking goes over a time (eg. 13:00) then add to count
$sql =
"
SELECT DAYNAME(arrivalTime) AS day, COUNT(*) AS count
FROM bookings
WHERE HOUR(arrivalTime) = 10
AND DAYNAME(arrivalTime) = 'Monday'
";
$result = $conn->query($sql);
if ($result->num_rows > 0)
{
while($row = $result->fetch_assoc())
{
$this->monday_10 = $row["count"];
}
}
else
{
echo "0 results";
}
}
As you can see, the time in this example (13.00) and day (Monday) is manually put in. How can I change this so it gets the time / day from the table and keep is as the same function for every td?
Furthermore, I would like to alter my SQL query (as shown in the PHP get_CalendarCount function) so that it checks if a booking in the database goes over a time (eg. arrivalTime 10:00 - pickupTime 12:00 - both 10:00 and 11:00 need to count as the booking is for the hours 10:00 & 11:00 (1 hour each):
Would really appreciate help as I'm a bit stuck here, can't really find anything for this solution.
This is not answering the logic, you should change but the question of using variables in your query, so you don't have to manually put them in. For your question about making the hour and dayname variable you need to change this:
public function get_CalendarCount($conn)
{
$sql ="SELECT DAYNAME(arrivalTime) AS day, COUNT(*) AS count
FROM bookings WHERE HOUR(arrivalTime) = 10 AND DAYNAME(arrivalTime) = 'Monday'";
into:
public function get_CalendarCount($conn,$hour,$dayname)
{
$sql ="SELECT DAYNAME(arrivalTime) AS day, COUNT(*) AS count
FROM bookings WHERE HOUR(arrivalTime) = ".$hour." AND DAYNAME(arrivalTime) = '" . $dayname ."'";

Everything is Out of Order: Php - MySQL

I am trying to create a php script that gets values from a MySQL database, displays a header with the time_stamp that comes from an array, and a sub header with a value called "working_ra" with values underneath those categories. The values that go underneath both categories are being displayed in a table. I am sorting the values of the working_ra in the query so I can run a while loop saying that if they're not the same to display the next working_ra and continue echoing values. Here is my code:
foreach ($date as $i) {
echo "<pre>"."<h2>".$i."</h2>"."</pre>";
$result = mysqli_query ($con, "SELECT * FROM Signing WHERE value1 = 'Ings' AND time_stamp = '$i' ORDER BY working_ra");
$num_results = mysqli_num_rows($result);
$row = mysqli_fetch_array($result);
$desk = $row["working_ra"];
echo "var_desk starting value ","<b>", $desk,"</b>";
echo "<table border='1'>";
echo "<tr>";
echo "<td>", $row["first"],"</td>";
echo "</tr>";
while ($row = mysqli_fetch_array($result)) {
if ((string)$desk != (string)$row["working_ra"]) {
echo "</table>";
$desk = $row["working_ra"];
echo "var_desk next value ","<b>",$desk,"</b>";
echo "<br />";
echo "<table border='1'>";
}
echo "<tr>";
echo "<td>", $row["first"],"</td>";
echo "</tr>";
}
$result->free();
}
$con->close();
Everything works fine until it hits to the second "desk" name. Then the tables that are supposed to be with the next value get shifted to the next date. Here is what it looks like on the page:
aSFashagh, Jeremy, Jeremy, and Johnny are all supposed to be under (Phil, January 10 2013) but is shifted down into the next date and working_ra (Phil, January 20 2013). zffaA, andsdfdsggsdhj are all supposed to be under (Phil,January 20 2013) but are under (Phil, February 25 2013) instead. Whats weird is that the method did work WITHOUT trying to put all of the values in tables.
My assumption is that it could be the ordering of which the table tags are ending and starting, but I have tried numerous amounts of things and still cannot figure out what is wrong.
EDIT
Sorry its very confusing to say. But im trying to get it to where everything is shifted up the way its supposed to be. Where the values of "first" belong with their corresponding time_stamp and working_ra. For instance, the value of Johnny in the MySQL db has a value of working_ra - Phil and a value of time_stamp - January 10, 2013. However as you can see, Johnny is not underneath (Phil, January 10 2013) instead January 20, 2013. Its not the query thats the problem, it has something to do with the while loop and the table and I just can't figure it out.
The only two values that are correct are Zack and Why which have corresponding values of (working_ra = "Bob", time_stamp = "January 10, 2013")
I believe your problem is with the mysql row pointer. You already used mysqli_fetch_array once before the while loop therefore shifting the current mysql row to the next row.
This code
mysqli_data_seek($result, 0);
will reset the pointer.
Place it right before your while loop.
Figured out what the problem was. I needed to add a "/table" tag when the while loop breaks.

Displaying results depending on its date (month & year)

I have load of data in the DB and each row has a date column
Currently im pulling all the results onto a page but i want to split it up into months.
I have buttons on my page that when clicked should display only the appropriate results, for example when the button January 2012 is click all the results for that month will be displayed
Heres an example of what im trying to achieve:
http://i.stack.imgur.com/PY7iN.jpg
=================================================================================
<?php
$con = mysql_connect("localhost", "username", "pass");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("database", $con);
$result = mysql_query("SELECT * FROM tablename");
$num_rows = mysql_num_rows($result);
echo "<table border='0' cellspacing='0'>";
while($row = mysql_fetch_array($result))
{
$i++;
if($i%2==0) $class="cell1"; else $class="cell2";
echo "<tr class='$class'>";
echo "<td>".$row["firstname"]." ".$row["lastname"]." thinks that it will happen on
<span class=datecolor>".date('l jS F Y',strtotime($row['date']))."</span></td>";
echo "</tr>";
}
echo "</table>";
mysql_close($con);
?>
=========================================================================
Im looking for a little help on how i can display the results for each month by clicking on the buttons without it appearing all at the one time.
Also the when the page is first viewed id like it to automatically show the results for the current month, for example it if viewed now it would display the August results
Hope you can help
To address your first question (displaying one month at a time), your best bet is to make your database do all of the work for you. Right now your SQL SELECT statement looks like
SELECT * FROM tablename
You want to add a WHERE clause that will restrict this query to only show you rows for a certain month… something like
SELECT * FROM tablename WHERE date BETWEEN '05/01/2011' AND '05/31/2011'
You may need to tweak this for your particular database engine or setup. Here's one WHERE tutorial; you can find tons more on the web.
You can have all your buttons be links to the page with a query string that specifies the month (for example: www.mysite.com/mypage?month=september). Then get the month from the query string and only select the rows that are in that month.
See:
PHP parse_str()
$_SERVER['QUERY_STRING']
MySQL Select a Date Range
Something like
$month = isset($_GET['month']) ? intval($_GET['month']) : 0;
$year = isset($_GET['year']) ? intval($_GET['year']) : 0;
if( empty($month) ){
$month = date('n');
}
if( empty($year) ){
$year = date('Y');
}
$query = mysql_query('SELECT * FROM table_name WHERE MONTH(date_field)="'.$month.'" AND YEAR(date_field)='.$year.'"');
// or maybe use BETWEEN syntax
while( false!==($row=mysql_fetch_assoc($query)) ){
// do something...
}
Year is needed because one month number may belong to diffent year number (03-2010,03-2011 etc..), and, so when your data covers dates from different years, you cannot determine what data you need only having month

Categories