Codeigniter query to data from database for each day - php

I have a $from date and $to date with me so I want to fetch four values from the the database for days in between $from and $to and including $from and $to . If the data does not exist for a day in the database then zero must in placed as the value for the missing values.
So how would I write a query in codeigniter to make it happen and the corresponding date should be stored in the result for a particular row .

My previous solution is that I using PHP to check and set zero for missing date. But I have some new solutions and you can try
Create a table to store dates and left/right join with your table
Or create temporary table using stored procedure and join. Temporary will be auto deleted when a session is expired
Using UNION with select statement
There're many answers on StackOverflow
MySQL how to fill missing dates in range?
MySQL group by date and count including missing dates
Running total over date range - fill in the missing dates
MySQL to fill in missing dates when using GROUP BY DATE(table.timestamp) without joining on temporary table

i think you solution needs to be actually in PHP and not sure if you can get what you are looking for directly from MYSQL just by a query. As from what i understand you want to run a query, get all records that are in your defined date range and then have dates that has no records have an empty row (or with any other value you decide...).
I would actually run the same query you have for selecting rows between the daterange and use DatePeriod Class to generate an array of all days between the start and end dates.
$begin = new DateTime( '2012-08-01' );
$end = new DateTime( '2012-10-31' );
$end = $end->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach($daterange as $date){
echo $date->format("Y-m-d") . "<br>";
}
With this we will be able to run over each day from the $from_date to the $end_date.
Next we will need to go other the rows from the DB and see on which days there are records and where no according the the daterange object we have.
Here is an approach that would work i believe, it's not the cleanest sample but some additional work on it and you can make it a bit prettier, but i think that will work for what you need.
The Database section in the code is not in Codeigniter but as it is only getting a simple query you should not have any trouble changing that.
// set the start & end dates
$from_date = '2012-09-11';
$to_date = '2012-11-11';
// create a daterange object
$begin = new DateTime($from_date);
$end = new DateTime($to_date );
$end = $end->modify( '+1 day' );
$interval = new DateInterval('P1D');
$daterange = new DatePeriod($begin, $interval ,$end);
$sth = $dbh->prepare("SELECT col1, dateCol from tb WHERE dateCol>'".$from_date."' AND dateCol<'".$to_date."' order by dateCol ");
$sth->execute();
$rows = $sth->fetchAll(PDO::FETCH_ASSOC);
$rowsByDay = array(); // will hold the rows with date keys
// loop on results to create thenew rowsByDay
foreach($rows as $key=>$row) {
$rowsByDay[strtotime($row['dateCol'])][] = $row; // add the row to the new rows array with a timestamp key
}
// loop of the daterange elements and fill the rows array
foreach($daterange as $date){
if(!isset($rowsByDay[strtotime($date->format("Y-m-d"))])) // if element does not exists - meaning no record for a specific day
{
$rowsByDay[strtotime($date->format("Y-m-d"))] = array(); // add an empty arra (or anything else)
}
}
// sort the rowsByDay array so they all are arrange by day from start day to end day
ksort($rowsByDay);
// just for showing what we get at the end for rowsByDay array
foreach ($rowsByDay as $k=>$v) {
echo date('Y-m-d',$k);
var_dump($v);
echo '<hr/>';
}
Hope this gets you on the right way...

Hope this helps,
$this->db->where('date_column >= ',$date_given_start);
$this->db->where('date_column <= ',$date_given_end);
$this->db->get('TABLE_NAME')->result();
// if column is datetime
$this->db->where('DATE(date_column) >= ',$date_given_start);
$this->db->where('DATE(date_column) <= ',$date_given_end);
$this->db->get('TABLE_NAME')->result();

Related

Mysql insert records that are not in the same table

Hello good day I have these 4 records as you see below.
-----fecha---
2018/03/01 0:05
2018/03/01 0:15
2018/03/01 0:20
--------------
They are registered in mysql with their respective id.
what I want to do from the mysql if there is a method or something that shows me the records that do not match
For example, I have several records, these records go in 5 minutes to 5 minutes as seen in the table, what I want to do is that mysql shows me the record that is not there, for example, it is not the
2018/03/01 0:10 and that only shows that
I appreciate your help.
You should fix 0: as it's not a valid hour value.
You can do it like the following using DateTime, but your need to define the start and end values, I'm presuming you're doing that in selecting your "fecha" data.
<?php
// query this in a select
$result = [
'2018/04/12 00:05',
'2018/04/12 00:15',
'2018/04/12 00:20',
];
// define start/end by first and last items in array
$begin = DateTime::createFromFormat('Y/m/d H:i', min($result));
$end = DateTime::createFromFormat('Y/m/d H:i', max($result));
$interval = new DateInterval('PT5M'); // plus time 5 min
$daterange = new DatePeriod($begin, $interval ,$end);
// build an array to compare it with
foreach ($daterange as $date){
$range[] = $date->format("Y/m/d H:i");
}
// array diff out the differences
print_r(array_diff($range, $result))
?>
https://3v4l.org/faWEY
Result:
Array
(
[1] => 2018/04/12 00:10
)

Repeat insert query with a different date given by a frequency

I'm building a system where an user can register activities. However the activities registered can repeat over the course of the year.
In order to prevent having the need that the user has to fill in the form to create an activity multiple times for each different date, I had the idea to add a textbox and a dropdown to the form to allow the user to fill in a frequency. The user can fill in a number in the textbox (for example "2") and select a value from the dropdown (for example "week"). So from that selection the activity has to be added to the database for the next 2 weeks on the same day.
However I have no idea how to let PHP adjust the date and add exactly 7 days to the selected date and repeat the same insert query with the new date, for every week/month/year selected from the given frequency.
EDIT 1:
I've tried this so far:
while ($i> 0)
{
$query2 = $this->db->connection->prepare("INSERT INTO activity(Act_Startdate) values (?)");
$query2->bind_param("s", $Startdate);
$query2->execute();
$Dates = date('d-m-Y', strtotime($Startdate . '+ 1 days'));
$Startdate = date('d-m-Y', strtotime($Dates));
$i--;
}
The first date insertion works, but the second one results 0000-00-00.
Read more about :
Date Time in PHP.
Date Interval in PHP
$numberPostedByUser = $_POST['your_input_name_in_form'];
$currentDate = new \DateTime(); // Getting current date
$iterator = 1;
while ($iterator <= $numberPostedByUser) {
$currentDate->add(new \DateInterval('P1D')); // Adding interval of one day in current date
$startDate = $currentDate->format('Y-m-d H:i:s'); // converting that day in convenient format we required
$query2 = $this->db->connection->prepare("INSERT INTO activity(Act_Startdate) values (?)");
$query2->bind_param("s", $startDate);
$query2->execute();
$iterator++; // increasing iterator for next loop
}
Hope may this code will help you.

Find if time is within range in format HH:MM-HH:MM

On my website, I have entries in the format TITLE#HH:MM-HH:MM#LOCATION. I can easily split this into 3 different array keys with explode("#",..., and display the data, but now I am working on creating a function to return whether the current timestamp is within the "HH:MM-HH:MM".
HH:MM-HH:MM is in the format of 12:20-13:10, where the first time is the start time of the event, and the second time is when the event ends. I'm trying to detect whether the time the page loads and time() is called is within 12:20-13:10.
How would I go about doing this? I have tried creating some code but I'm not sure how to accomplish this cleanly.
Thanks!
UPDATE --
$tEvent = explode("-", $arr[1]);
$now = new DateTime(date("Y-m-d H:i:s",$time), new DateTimeZone('America/Detroit'));
$start = new DateTime($tEvent[0], new DateTimeZone('America/Detroit'));
$end = new DateTime($tEvent[1], new DateTimeZone('America/Detroit'));
if ($now->format('U') >= $start->format('U') && $now->format('U') <= $end->format('U')) {
//within time
}
You can do this with several different methods. Personally, I like to work with Datetime class to manipulate dates in php.
$timeEvent = "12:20-13:10"; // your string with start and end of the event
$tEvent = explode("-", $timeEvent); // split in 2 (0 is start, 1 is end)
$now = new Datetime("NOW"); // gets the actual date
$start = new Datetime($tEvent[0]); // create datetime object with start date
$end = new Datetime($tEvent[1]); // create datetime object with end date
if ( $now > $start && $now < $end ) // check if now is between start and end
{
echo "It's event time!";
}

MySQL Query with Idiorm and Date Issue

I want to use a chart on some of my data and generate the values based on selected dates (with a date picker). I've stolen most of the stuff on the web and might have only a simple questions.
Here is the Idiorm query:
if (isset($_GET['start']) AND isset($_GET['end'])) {
$start = $_GET['start'];
$end = $_GET['end'];
$data = array();
// Select the results with Idiorm
$results = ORM::for_table('tbl_data')
->where_gte('date', $start)
->where_lte('date', $end)
->order_by_desc('date')
->find_array();
// Build a new array with the data
foreach ($results as $key => $value) {
$data[$key]['label'] = $value['date'];
$data[$key]['value'] = $value['rev'];
}
echo json_encode($data);
}
The $start and $end are from my datepicker and in yyyy-mm-dd format. The only thing I don't know how to do is how to change the ->where_gte statement. As you can see it's querying the db for the field date. In my db I have three fields, year, month and day.
Is there a way to combing the three fields year, month and day into one expression i.e. maybe ->where_gte('year'&'month'&'day', $start)???
I tried searching and searching but maybe have the wrong keywords or to less knowledge.
Thanks in advance for any help!
Since you have three fields in the DB, you need three where_gte clauses:
...
->where_gte('year', substr($start, 0, 4) // or most suitable date_format
->where_gte('month', substr($start, 5, 2) // or most suitable date_format
...
Hope it helps.
You can manage date format using MySql DATE_FORMAT() Function. E. G.:
// Select the results with Idiorm
$results = ORM::for_table('tbl_data')
->where_gte('date', "DATE_FORMAT($start, '%Y-%m-%d')")
->where_lte('date', "DATE_FORMAT($end, '%Y-%m-%d')")
->order_by_desc('date')
->find_array();

Issues with date_diff php, comparing nowtime/nowdate, to SQL saved datetime

$today = date('Y-m-d H:i:s'); // get date SQL format
$today = date('Y-m-d H:i:s', strtotime($today)); // get date SQL format¨
$today = new DateTime($today);
$compare = new DateTime($row['date']);
$interval = date_diff($today, $compare);
echo $interval->format("%H") .'<br>';
echo $interval->format("%i") .'<br>';
echo $interval->format("%s") .'<br>';
die();
Something is very wrong, i want the time difference between a post in my SQL database and NowTime
$row['date']
is 2013-03-25 14:22:53 inserted as datetime in my table, for some reason i get a odd downcounting output?
Use the database query to do it.
SELECT DATEDIFF(date,NOW()) as DateDifference FROM table
Unsure why people keep insiting on doing db date comparisons in php rather than the DB. Its considerably quicker and less resource and tidier code to do it on query then just compare the result as it spits out the day differential of the dates. (date may be a protected column name so you may need to enclose it in ` or change it to a different column name.

Categories