I have a tricky one here.
I have a number of results in a table, this table has id, market, date and points.
I want to get all the records for a given month and then output all the points for each day, in order.
I'm not sure of the best way to do this? Her are my options, well my ideas, I could set a loop that will execute for every day of the given month, this will run a query to find every record for that day and will do this for every day of the month, this will then be easy to order a format the records but i'm thinking its not a good idea to query the database that many times.
The second idea i to query the database for all the records for that date, order them by the date. However i can see come problems here when outputting the information for each day, well it will be a long job then the first i think.
Any ideas? anyone done something like this before and could lend a helping hand? Any advise would be more than welcome!
Thanks.
while($row = mysql_fetch_array($getresults))
{
$day = FALSE;
foreach ($row as $row)
{
$day_res = date("Y-m-d H:m:s", strtotime($row["date"]));
if (!$day || $day != $day_res)
{
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $row['date'] . " " . $row["id"] . ": " . $row["market"] .
"/" . $row["points"] . "<br/>";
}
}
This is the output i get from it:
1970-01-01 00:01:00
3 3: 3/3
3 3: 3/3
2012-01-13 09:01:06
E E: E/E
E E: E/E
1970-01-01 00:01:00
2 2: 2/2
2 2: 2/2
- -: -/-
- -: -/-
1970-01-01 00:01:00
4 4: 4/4
4 4: 4/4
and that more or less repeats for a while.
Thanks again.
If that date is only a date, then you could try something like this:
SELECT t.date, SUM(t.points) FROM table t WHERE date BETWEEN [STARTDATE HERE] AND [ENDDATE HERE] GROUP BY t.date
What it does? It selects everything the date & the sum of the points of that day, because we group all the results based on a day. So for every unique date in your table you will get a row with a result. Use the WHERE date statement to define from which month you need the selection.
Addition: the thing shown is only valid if date is in format like: YYYY-MM-DD. In case you have a timestamp (YYYY-MM-DD HH:ii:ss) you could try to change the query to:
SELECT t.date, SUM(t.points) FROM table t WHERE date BETWEEN [STARTDATE HERE] AND [ENDDATE HERE] GROUP BY DAYOFMONTH(t.date)
This ensures that you will group them by the day of the month (1 to 31) based on the dates from your table.
at first the query to get all for a given month ordered by date:
SELECT * FROM `table` WHERE `date` LIKE '2012-01%' ORDER BY date;
here the php loop to show it:
$day = FALSE;
foreach ($results as $result){
$day_res = date("d", strtotime($result["date"]));
if (!$day || $day != $day_res){
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $result["id"].": ".$result["market"]."/".$result["points"]."<br/>";
}
Ok here for your structure:
$day = FALSE;
while($row = mysql_fetch_array($getresults))
{
$day_res = date("Y-m-d H:m:s", strtotime($row["date"]));
if (!$day || $day != $day_res)
{
$day = $day_res;
echo '<h1>'.$day.'</h1>';
}
echo $row['date'] . " " . $row["id"] . ": " . $row["market"] .
"/" . $row["points"] . "<br/>";
}
Related
I want to add particular days to current date. where days are taking from database field. It adds to the present date properly but at next day, date is going to update to the present date again.so how to keep date unchanged. It should take only once in PHP
$day= $cur["Days"];
if(($cur["Days"]) == 0){
$new = '';
} else {
$Date = date('20y-m-d');
$new = date("20y-m-d", strtotime($Date . ' + ' . $day . ' days'));
}
input if $day=1,$day+$new
output= jan19,this is the output of one row and my problem is it should remain as it is for this row but now for next day it is going to change to jan20 that should not happen
Context
I am building a simple recommendation script that serves to provide a user with the next upcoming date for a particular day of the week that he/she has booked the most.
(i.e. JohnDoe's most popular day to book is a Thursday, and the date of the next Thursday to come up is 2019/03/07)
This is what I am dealing with :
<?php
$date = new DateTime();
$date->modify('next thursday');
echo $date->format('Y-m-d');
?>
<?php require "snippets/get_booking_recommended_day.php" ?>
The first PHP code returns the next upcoming date for whatever day is asked. It works as it should. The PHP require references code from another folder that returns the users most popular day, in String format. (eg Monday, Tuesday). It also works.
My issue comes when trying to get the first bit of code to understand what is being returned from the 2nd bit of code.
I've attempted the following...
<?php
$date = new DateTime();
$date->modify('next' require "snippets/get_booking_recommended_day.php");
echo $date->format('Y-m-d');
?>
I've tried every variation possible. Nothing seems to work.
I'm quite new to PHP, and im 90% sure my coding practice is terrible but I am trying my best to grasp it - but so far this simple issue is beyond me.
Please help.
APPENDICES
Filename: snippets/get_booking_recommended_day.php
(Return the most booked day of the last 3 months by the user currently in session)
<?php
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
// Asks the qry: Of the last 90 days, what is the most booked day of the week for the current member in session?
// Min date is CURRENT_DATE() -100 instead of CURRENT_DATE() -30, because the MySQL function CURRENT_DATE() prints the date in an int format (YYYYMMDD) with no date formatting. Thus, to get the date a month ago, we must subtract this int by 100 so as to remove 1 from the 6th number in the series of numbers. Which is the 2nd M number.
$sql = "SELECT DATE_FORMAT(tbl_booking.booking_date, '%W'), COUNT(DATE_FORMAT(tbl_booking.booking_date, '%W')) AS mostpopularday
FROM tbl_booking
WHERE tbl_booking.member_ID=$_SESSION[member_ID]
AND tbl_booking.booking_date <= CURRENT_DATE()
AND tbl_booking.booking_date >= CURRENT_DATE() -300
GROUP BY DATE_FORMAT(tbl_booking.booking_date, '%W')
ORDER BY mostpopularday DESC
LIMIT 1";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo $row["DATE_FORMAT(tbl_booking.booking_date, '%W')"];
}
} else {
// Return Nothing.
}
?>
Filename : pagebooking.php
(This is the datepicker that is located inside my pagebooking.php, its purpose is to choose the day of a booking. My hope is to populate this field with the recommended date that will be generated from the 2 PHP scripts above.).
<input name="new_booking_date" width="276" placeholder="Date" class="form-control input-md" type="date" max="<?php echo date("Y-m-d", strtotime("+30 day")); ?>" min="<?php echo date("Y-m-d", strtotime("+1 day")); ?>" required="" />
Issue resolved.
<?php
// If there are any values in the table, display them one at a time.
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
// Asks the qry: Of the last 90 days, what is the most booked day of the week for the current member in session?
// Min date is CURRENT_DATE() -100 instead of CURRENT_DATE() -30, because the MySQL function CURRENT_DATE() prints the date in an int format (YYYYMMDD) with no date formatting. Thus, to get the date a month ago, we must subtract this int by 100 so as to remove 1 from the 6th number in the series of numbers. Which is the 2nd M number.
$sql = "SELECT DATE_FORMAT(tbl_booking.booking_date, '%W'), COUNT(DATE_FORMAT(tbl_booking.booking_date, '%W')) AS mostpopularday
FROM tbl_booking
WHERE tbl_booking.member_ID=$_SESSION[member_ID]
AND tbl_booking.booking_date <= CURRENT_DATE()
AND tbl_booking.booking_date >= CURRENT_DATE() -300
GROUP BY DATE_FORMAT(tbl_booking.booking_date, '%W')
ORDER BY mostpopularday DESC
LIMIT 1";
$result = $mysqli->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
$recommended_day = $row["DATE_FORMAT(tbl_booking.booking_date, '%W')"];
$date = new DateTime();
$date->modify('next '.$recommended_day);
echo $date->format('Y-m-d');
}
} else {
}
?>
I am trying to write a script to pull dates for the next 7 days and put them into a div for each date :
echo '<div class="dateboxcontainer">';
for($i=0; $i<=6; $i++){
echo '<div class="datebox"><div class="topdate">'.strtoupper(date("D d", mktime(0, 0, 0, 0, date("d")+$i, 0))."\n").
'</div><div class="bottomdate">An appointment for the day</div></div>';
}
echo '</div>';
Im now trying to pull data from my database from two fields 'datedroppingoff' and 'datepickingup', which are formatted like this '2013-07-10 14:29:28'.
Im kind of stuck though as im not sure what query to write to put the appointments for each day into each day div where 'some info' currently sits.
Im guessing it would be something like
Select * FROM jobdetails WHERE datedroppingoff OR datepickingup = WHATEVER DAY IS BEING ECHO'D OUT
but im not quite sure how I can compare the date stored in jobdetails for that row to the date being echo'd out ?.
Edit>>>>>
Thanks for the answers below, iv managed to come up with the following, it echos out the date boxes ok, but doesnt bring in any data, so im not sure if I have the sql part correct ?.
echo '<div class="dateboxcontainer">';
$eventdata = <<<SQL
SELECT *
FROM `jobdetails`
SQL;
if(!$events = $db->query($eventdata)){
die('There was an error running the query [' . $db->error . ']');
}
// read first event
if ($nextEvent = mysql_fetch_assoc($events)) { // here is the first one
extract($nextEvent); // prepare its variables
// use the event date it to control the inner loop
$nextDate = $datedroppingoff;
} else // no events?
$nextDate = 0; // prepare a fake date value
// calculate today date
$currentDate = mktime();
// loop on the dates for the next 7 days
for ($i = 0 ; $i < 7; $i++) {
$currentEvents = "";
// loop to print every event for current day (first one already extracted)
while ($nextDate == date("Y-m-d", $currentDate)) { // next event occurs today
// here prepare the var containing the event description
// BTW, I'd use a list for the events
$currentEvents .= "· $name<br>"; // use every field you need from current DB row
// read next event
if ($nextEvent = mysql_fetch_assoc($events)) { // here is the next one
extract($nextEvent); // prepare its variables
// use the event date it to control the inner loop
$nextDate = $datedroppingoff;
} else // no more events?
$nextDate = 0; // prepare a fake date value
}
echo "
<div class='datebox'>
<div class='topdate'>" . strtoupper(date("D d m Y", $currentDate)) . "</div>
<div class='bottomdate'>$currentEvents</div>
</div>";
$currentDate = strtotime("+1 day", $currentDate);
}
echo '</div>';
Can you use something like this:
SELECT * FROM `jobdetails` WHERE (`datedroppingoff ` > '2013-07-01 00:00:00' AND `datedroppingoff ` '2013-07-02 00:00:00') OR (`datepickingup ` > '2013-07-01 00:00:00' AND `datepickingup ` '2013-07-02 00:00:00');
This will have to be repeated per day (i.e. for each of the 5 days)
To do a nice loop, use an array populated with the next 5 dates as strings. Then do a foreach over the dates and run this query.
If you want all dates from now and for the next 5 days, you could use:
WHERE
`datedroppingoff` BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 5 DAY) OR
`datepickingup ` BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 5 DAY)
Let's see how I'd proceed (by the way, this is my first answer, so I'm a little excited...)
First, some basic assumptions for this ultra-fast script (sorry, not so much time now to test it thoroughly).
your Appointment table has a field with the date of the appointment
your result resource ($events) contains only the rows for the current week
the resulting rows are sorted by the date field, ascending (from oldest to newest)
Try this (I've changed a bit your original code, sorry)
// read first event
if ($nextEvent = mysql_fetch_assoc($events)) { // here is the first one
extract($nextEvent); // prepare its variables
// use the event date it to control the inner loop
$nextDate = $DB_field_with_event_date;
} else // no events?
$nextDate = 0; // prepare a fake date value
// calculate today date
$currentDate = mktime();
// loop on the dates for the next 7 days
for ($i = 0 ; $i < 7; $i++) {
$currentEvents = "";
// loop to print every event for current day (first one already extracted)
while ($nextDate == date("Y-m-d", $currentDate)) { // next event occurs today
// here prepare the var containing the event description
// BTW, I'd use a list for the events
$currentEvents .= "· $your_desc_field<br>"; // use every field you need from current DB row
// read next event
if ($nextEvent = mysql_fetch_assoc($events)) { // here is the next one
extract($nextEvent); // prepare its variables
// use the event date it to control the inner loop
$nextDate = $DB_field_with_event_date;
} else // no more events?
$nextDate = 0; // prepare a fake date value
}
echo "
<div class='datebox'>
<div class='topdate'>" . strtoupper(date("D d m Y", $currentDate)) . "</div>
<div class='bottomdate'>$currentEvents</div>
</div>";
$currentDate = strtotime("+1 day", $currentDate);
}
Tried a couple of times on fake data and it should work. IMHO better to directly alias the date field to get the nextDate var directly from the DB, so avoiding the rows,
$nextDate = $DB_field_with_event_date;
I used this in the end which seems to do the job ! :)
// Date box container
echo '<div class="dateboxcontainer">';
// Loop through and create a date for the next 7 days
$days = new DatePeriod(new DateTime, new DateInterval('P1D'), 7);
foreach ($days as $day) {
echo '<div class="datebox">';
echo '<div class="topdate">';
echo strtoupper($day->format('D d')) . PHP_EOL;
echo '</div>';
// Get the names for each day
$theday = strtoupper($day->format('Y-m-d'));
$sqldate = <<<SQL
SELECT *
FROM `jobdetails`
WHERE datedroppingoff = '$theday' OR datepickingup = '$theday'
SQL;
if(!$resultdate = $db->query($sqldate)){
die('There was an error running the query [' . $db->error . ']');
}
while($rowdate = $resultdate->fetch_assoc()){
echo $rowdate['name'];
}
//
echo '</div>';
}
echo '</div>';
//
I have a table called schedule and a column called Date where the column type is date. In that column I have a range of dates, which is currently from 2012-11-01 to 2012-11-30. I have a small form where the user can enter a range of dates (input names from and to) and I want to be able to compare the range of dates with the dates currently in the database.
This is what I have:
////////////////////////////////////////////////////////
//////First set the date range that we want to use//////
////////////////////////////////////////////////////////
if(isset($_POST['from']) && ($_POST['from'] != NULL))
{
$startDate = $_POST['from'];
}
else
{
//Default date is Today
$startDate = date("Y-m-d");
}
if(isset($_POST['to']) && ($_POST['to'] != NULL))
{
$endDate = $_POST['to'];
}
else
{
//Default day is one month from today
$endDate = date("Y-m-d", strtotime("+1 month"));
}
//////////////////////////////////////////////////////////////////////////////////////
//////Next calculate the total amount of days selected above to use as a limiter//////
//////////////////////////////////////////////////////////////////////////////////////
$dayStart = strtotime($startDate);
$dayEnd = strtotime($endDate);
$total_days = abs($dayEnd - $dayStart) / 86400 +1;
echo "Start Date: " . $startDate . "<br>End Date: " . $endDate . "<br>";
echo "Day Start: " . $dayStart . "<br>Day End: " . $dayEnd . "<br>";
echo "Total Days: " . $total_days . "<br>";
////////////////////////////////////////////////////////////////////////////////////
//////Then we're going to see if the dates selected are in the schedule table//////
////////////////////////////////////////////////////////////////////////////////////
//Select all of the dates currently in the schedule table between the range selected.
$sql = ("SELECT Date FROM schedule WHERE Date BETWEEN '$startDate' AND '$endDate' LIMIT $total_days");
//Run a check on the query to make sure it worked. If it failed then print the error.
if(!$result_date_query = $mysqli->query($sql))
{
die('There was an error getting the dates from the schedule table [' . $mysqli->error . ']');
}
//Set the dates to an array for future use.
// $current_dates = $result_date_query->fetch_assoc();
//Loop through the results while a result is being returned.
while($row = $result_date_query->fetch_assoc())
{
echo "Row: " . $row['Date'] . "<br>";
echo "Start day: " . date('Y-m-d', $dayStart) . "<br>";
//Set this loop to add 1 day to the Start Date until it reaches the End Date
for($i = $dayStart; $i <= $dayEnd; $i = strtotime('+1 day', $i))
{
$date = date('Y-m-d',$i);
echo "Loop Start day: " . date('Y-m-d', $dayStart) . "<br>";
//Run a check to see if any of the dates selected are in the schedule table.
if($row['Date'] != $date)
{
echo "Current Date: " . $row['Date'] . "<br>";
echo "Date: " . $date . "<br>";
echo "It appears as though you've selected some dates that are not in the schedule database.<br>Please correct the issue and try again.";
return;
}
}
}
//Free the result so something else can use it.
$result_date_query->free();
As you can see I've added in some echo statements so I can see what is being produced. From what I can see it looks like my $row['Date'] is not incrementing and staying at the same date. I originally had it set to a variable (currently commented out) but I thought that could be causing problems.
I have created the table with dates ranging from 2012-11-01 to 2012-11-15 for testing and entered all of this php code onto phpfiddle.org but I can't get the username provided to connect.
Here is the link: PHP Fiddle
I'll be reading through the documentation to try and figure out the user connection problem in the meantime, I would really appreciate any direction or advice you can give me.
PHP code (relevant)
$db = '2011-02-28'; $a = '2011-02-01';
and this is the part of the query
LEFT JOIN
abc
ON
abc.date between '$a' and '$db'
This query show following results :
1 2011-02-08
6 2011-02-09
6 2011-02-11
1 2011-02-13
but what i want is to get 0 as a result if there's n rows for other dates.
You can't do that (not without joining a table containing all dates, at least).
Displaying the 0s for dates with no data is the job of your application, not the database. It's trivial, just write a loop from the start date to the end date, and output the 0 for those dates with no rows in your result set.
SQL's job is to tell you what data is there, not what isn't.
while ($row = mysql_fetch_array($result)) {
$results[$row['date']] = $row['count'];
}
for ($time = strtotime('2011-02-01'); $time <= strtotime('2011-02-28'); $time += 86400) {
$datestr = date('Y-m-d', $time);
if (isset($results[$datestr])) {
echo "Count for date $datestr: " . $results[$datestr];
} else {
echo "Count for date $datestr: 0";
}
}
From the limited information you give about what problem you are trying to solve I would guess you are trying to find "free appointments" or similar.
If so then this should help you out. http://www.artfulsoftware.com/infotree/queries.php?&bw=1280#98
This website has a number of query patterns that will help your thinking and design of your database.