Getting MySQL results based on date by current month in Codeigniter - php

I currently get the last 30 days results like this.
public function commission_month(){
$status = 'A';
$this->db->select_sum('LenderCommission');
$this->db->where(['Status' => $status ]) ;
$this->db->where('CompletedDate >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) ');
$query = $this->db->get('toutcome');
$result = $query->result();
return $result[0]->LenderCommission;
}
What i am really trying to do is get results for this current month.
And then when its the next month , its should do the same.

You can use a "like" query to get the information you need, assuming the dates are stored in a manner you can easily apply a like to.
Basically, the query will be something along the lines of ... AND CompletedDate LIKE 'YYYY-MM-%'... where YYYY and MM are valid year and months. This can be done in CodeIgniter by using the $this->db->like() builder:
$this->db->like('CompletedDate', date('Y-m'));
Your code then being:
public function commission_month(){
$status = 'A';
$this->db->select_sum('LenderCommission');
$this->db->where(['Status' => $status ]) ;
$this->db->like('CompletedDate', date('Y-m'));
$query = $this->db->get('toutcome');
$result = $query->result();
return $result[0]->LenderCommission;
}

Related

MySQL - INTERVAL 24 HOUR not working as expected

I am building a chart and for that extracting data from the past 24 hours, 48 hours, 1 week and 2 weeks.
I used INTERVAL statements for this purpose but they are not working as expected. I am using Laravel. Here is the function to extract the data:
public function range($range)
{
$data = new Main();
$data0 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'FiveRP')->get();
$data1 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'GTALife')->get();
$data2 = $data->whereRaw('updated_at >= DATE_SUB(NOW(), INTERVAL '.$range.')')->whereRaw('MINUTE(updated_at)>54')->orwhereRaw('MINUTE(updated_at)<6')->where('server_short_name', '=', 'GermanV')->get();
return compact('data0', 'data1', 'data2');
}
Here is the function that calls the view:
public function hours24()
{
$t = $this::range('24 HOUR');
return view('chart', $t);
}
But in the chart, I am getting results from 22nd of May as well which is the earliest date on DB. Which means that the code isnt working as expected although it is correct according to me. Is there something I am missing out?
I have found the solution. Actually in my code I am using an 'orwhereRaw' which means that I am implying an OR between all the where statements which is sadly not what I want.

Echo 0 for Mysql query with no results

I'm building an array of the number of calls I have for a particular client from a mysql db on a running list of the last 30 days. The code I have so far works for adding the days that have calls to the array but I need a show a '0' for the days that have no calls (no entries in the db). Here is me code so far:
$query="SELECT COUNT(*) FROM my_db WHERE client_phone='clint_phone#' GROUP BY calldate";
$result = mysql_query($query);
$data = array();
while ($row = mysql_fetch_row($result)) {
$data[] = $row[0];
}
I just need a way to show if today I had 30 calls and yesterday I had 0, I need it to show [30,0]. What I have only would show [30].
EDIT * I have a mysql db will columns client_phone, calldate. Im looking to build a graph using the data in an array. Each point of the graph will represent a day and the number of calls for that client on that day. Im building the above query to populate that array. I'm trying to count backwards thirty days and feed the total calls for each day into the array.
EDIT 2* I've got it almost there. I'm getting a problem in the 'foreach' area. Below is the code with two print_r()'s to dump the array. The first one looks good, but the second one shows some array entries getting over-written that shouldn't be:
$query="SELECT calldate, COUNT(*) FROM my_db WHERE client_phone='phone#' and calldate>='20130101' AND calldate<='20130107' GROUP BY calldate ORDER BY calldate";
$result = mysql_query($query);
$data = array();
while ($row = mysql_fetch_array($result)) {
$data[$row['calldate']] = $row[1];
}
$startDate = '20130101';
$endDate = '20130107';
$dates = array();
for($current = $startDate; $current != $endDate; $current = date('Ymd', strtotime("$current +1 day"))) {
$dates[] = $current;
}
$dates[] = $endDate;
print_r ($data);
echo "<br />";
foreach($dates as $date){
if (in_array($date, $data)) {
// that date was found in your db_date array(therefore had queries)
}else{
$data[$date] = 0; //date was not found in your db_array so we set that date with no queries to zero
}
}
print_r ($data);
I run this in a browser and I get this:
Array ( [20130101] => 1 [20130104] => 6 [20130105] => 2 [20130106] => 1 [20130107] => 3 )
Array ( [20130101] => 0 [20130104] => 0 [20130105] => 0 [20130106] => 0 [20130107] => 0 [20130102] => 0 [20130103] => 0 )
The top output looks good, just missing a zero assigned to dates not in the data[] array. The second array has zero's in the missing dates, but other overwrited that shouldn't have been.
Thanks for any help!
Finding every date that is in that timespan and doing a task for that does not really that standard of a solution. But depending if your host allows cron-tasks; if you were able to use cron tasks to automatically insert a 0 into your database at 11:59pm for that date if no querys were made that day; you could simply extract all dates.
If you do not want to do it with cron tasks I think you can manage it this way...
$startDate = '2009-01-28';
$endDate = '2009-02-04';
$dates = array();
for($current = $startDate; $current != $endDate; $current = date('Y-m-d', strtotime("$current +1 day"))) {
$dates[] = $current;
$dates[] = $endDate;
}
then do this
foreach($dates as $date){
if (array_key_exists($date, $data)) {
// that date was found in your db_date array(therefore had queries)
}else{
$data[$date] = 0; //date was not found in your db_array so we set that date with no queries to zero
}
}
This may need some minor adjustments because I have not tested it; but this should work; if not something very close to it should. Hope this helps.

Sort months array by position

I need to sort an array of months (alphabetical months) according to their months position and not alphabetical. My script returns a list of events and builds an multi-associative arrays based on years => months e.g. 2012 => array("August","March","September"), 2013 => array("April","May"); It builds the array perfectly, but I now need to sort the months so that it would return 2012 => array("March","August","September"), 2013 => ("April","May);
Here is the script I am currently using. Note that the date field in mysql is set to DATE and not VARCHAR, and dates are entered YYYY-MM-DD
public function returnMonthsArray() {
$sql = "SELECT `date` FROM `events` WHERE `status`=1 ORDER BY `name`";
$results = $this->db->returnMultiAssoc($sql);
$navArray = array();
foreach($results as $key => $value) {
$timestamp = strtotime($value["date"]);
$year = date("Y",$timestamp);
$month = date("F",$timestamp);
if(!array_key_exists($year, $navArray)) {
$navArray[$year] = array();
}
if(!in_array($month,$navArray[$year])) {
$navArray[$year][] = $month;
}
}
if(count($navArray)) {
return $navArray;
} else {
return false;
}
}
try this query
SELECT `date` FROM `events`
WHERE `status`=1 ORDER BY `name`"
GROUP BY MONTH(`date`)
Have a look to this post:
PHP and Enums
By specifing an enum like behavior for the months it would be easier to sort them the way that you want.
I hopw that this is helpful to you.

upper limit for active records in codeigniter

I have this function in my model the purpose of it is to get the stats of the past 30 days starting from the actual day, it was working fine before i reach 30th day then I found out it is counting from the oldest date, so I flipped the order_by from "ase" to "desc" but it seems still going back and counting before the oldest day and not giving me that data I want, so I'm wondering if there any way using codeigniter and give a starting point for the "limit" which should be the actual date.
function graph_data($id_person)
{
$this->db->limit(30); // get data for the last 30 days including the curent day
$this->db->where('personid',$id_person);
$this->db->order_by('date', 'ase');
$query = $this->db->get('stats');
foreach($query-> result_array() as $row)
{
$data[] = $row;
}
return $data;
}
limit returns in your case the last 30 rows. It has nothing to do with dates, unless you only add a row each day.
try using mysql Between
SELECT DATE_FORMAT(create_date, '%m/%d/%Y')
FROM mytable
WHERE create_date BETWEEN SYSDATE() - INTERVAL 30 DAY AND SYSDATE()
ORDER BY create_date ASC
Source -- https://stackoverflow.com/a/2041619/337055
I finally found the solution by giving a range or days, 29 days before the actual day without using BETWEEN and that works fine
<?php
function graph_data($id_person)
{
$today = date('Y-m-d');
$lastdate = date('Y-m-d', strtotime('-29 days', strtotime($today)));// 30 days ago
$this->db->where('personid',$id_person);
$this->db->where("date <= '$today'");
$this->db->where("date >= '$lastdate'");
$this->db->order_by('date', 'ase');
$query = $this->db->get('stats');
$data = array();
foreach($query-> result_array() as $row)
{
$data[] = $row;
}
return $data;
}

find the upcomming birthday in week [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How would I get the birthdays of friends who are celebrating their birthday this week, this month and next month using MYSQL and PHP?
I have a mysql table of users with fields UserId, Username, Birthdate (format YYYY-MM-DD). I want to display something on my homepage like this:
Upcoming birthdays:
Fred Smith 24 Aug
Bill Jones 27 Aug
Sarah Connor 1 Sep
David Cassidy 5 Sep
You get the idea - it generates a short list of which birthdays are coming up next, ignoring the year, just based on the day and month. I just have no idea how to do the query - any help would be appreciated!
You can use the mysql DATE_FORMAT() function. This should give you all the birthdays between the current day, and 7 days from now:
SELECT username, DATE_FORMAT(Birthdate,'%M %d') as 'birthday' FROM table WHERE DATE_FORMAT(Birthdate,'%m-%d') BETWEEN DATE_FORMAT(CURDATE(),'%m-%d') AND DATE_FORMAT(ADDDATE(NOW(), INTERVAL 7 DAY), '%m-%d') ORDER BY DATE_FORMAT(Birthdate,'%m-%d');
Another option is to create a function that will sit in a helper class, or go into your user class perhaps:-
/**
* Fetches a list of birthdays coming up in the following week
* #return array an array user's birthdays
*/
public function getBirthdays()
{
$date = new DateTime();
$date->setTime(0, 0, 1);
$today = $date->getTimestamp();
$week = new DateInterval('P7D');
$date->add($week);
$date->setTime(23, 59, 59);
$nextWeek = $date->getTimestamp();
$select = new Zend_Db_Select(Zend_Db_Table::getDefaultAdapter());
$select ->from('users', array('user_name', 'user_dob'))
->where('user_dob > ?', $today)
->where('user_dob < ?', $nextWeek);
return $select->query()->fetchAll();
}
Then you just do:-
$birthdays = $classYouMade->getBirthdays();
$html = '';
foreach($birthdays as $bday){
$html .= "Happy Birthday to {$bday['user_name']} on ";
$html .= date('jS F', $bday['user_dob']) . '<br/>';
}
echo $html;
It's quite long, but is self documenting (I think) and you can come back to it in a year's time and see exactly what is happening at a glance.
I have ofcourse made some assumptions about how you are storing date etc (I always use unix timestamps), but I'm sure you can adapt it to your use case if you wish to use it.
First, you need to retrieve a list of your users as follow:
$adapter = Zend_Db_Table::getDefaultAdapter()
$table = $adapter->getDbTable()
$select = $table->select();
$select->where('active = ?', true); // if needed
$user = $table->fetchAll($select);
Your getDbTable would be something very similar to the one in Zend Quickstart :
public function setDbTable($dbTable)
{
if (is_string($dbTable)) {
$dbTable = new $dbTable();
}
if (! $dbTable instanceof Zend_Db_Table_Abstract) {
throw new Exception('Invalid table provided');
}
$this->_dbTable = $dbTable;
return $this;
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('My_Users_DbTable_User');
}
return $this->_dbTable;
}
And in My/Users/DbTable/User a simpla class that contains:
class My_Users_DbTable_User extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
}
Finally, when you retrieved your data from the database, you can iterate through each row you fetched using current() and toArray()methods. See Zend_Db_Table_Row documentation for more details.
In order to display only the day and month of a birthdate, you can use Zend_Date which is pretty useful.
$date = "1970-12-10";
$d = new Zend_Date($date);
echo $d->toString(Zend_Date::DAY) . " " . $d->toString(Zend_Date::MONTH_NAME_SHORT);
// output: 10 Dec
You can query this with something like:
SELECT username, birthdate FROM table WHERE birthdate >= beginning_of_week AND birthdate <= end_of_week
You'd probably have to calculate the week range you want in whatever script you're querying from.
You should be able to get the list with a simple SQL query:
select UserId, Username, Birthdate from Users where Birthdate >= CURDATE() and Birthdate <= DATE_ADD(CURDATE(), INTERVAL + 2 WEEK) order by Birthdate ASC
Then you can format the text using DateTime::format() in PHP.
while ($row = mysql_fetch_assoc($res))
{
$birthday = new DateTime($row['Birthdate']);
print $row['Username']." ".$birthday->format('d M')."\n";
}

Categories