I am working in codeigniter, i have a below table of schemes, my problem is i want to show last updated data of each scheme. I dont know how to do that, please help.
my_table
scheme_code updated_on scheme_name
1 2015-04-13 One
3 2015-04-12 Three
4 2015-04-13 Four
3 2015-04-10 Three
3 2015-04-8 Three
1 2015-04-10 One
4 2015-04-11 Four
My Model
function show_last_updated_data(){
$this->db->select('*');
$this->db->from('my_table');
$this->db->order_by('updated_on', 'DESC');
$query = $this->db->get();
return $query->result();
}
Output Needed
scheme_code updated_on scheme_name
1 2015-04-13 One
3 2015-04-12 Three
4 2015-04-13 Four
My answer is based on #Syed Qarib. I modified it to be compatible with codeigniter active record format.
function show_last_updated_data() {
$this->db->select('*, str_to_date(updated_on, "%Y-%M-%d") As date', false); // false to skip escape
$this->db->from('scheme');
$this->db->group_by('scheme_code');
$this->db->order_by('date', 'DESC');
$query = $this->db->get();
return $query->result();
}
Edit
In another way,
function show_last_updated_data() {
$max = $this->db->select_max("updated_on")->group_by("scheme_code")->get('scheme')->result_array();
$updated_on = array();
if (count($max)) {
$updated_on = array_column($max, "updated_on"); // make sure your php version is >= 5.5
}
$this->db->select("*");
$this->db->from("scheme");
$this->db->where_in("updated_on", $updated_on);
$query = $this->db->get();
return $query->result();
}
Hope it will be useful for you.
Try this:
function show_last_updated_data(){
$this->db->select('*');
$this->db->from('my_table');
$this->db->group_by('scheme_name');
$this->db->order_by('updated_on', 'DESC');
$query = $this->db->get();
return $query->result();
}
You need to use group by it will retrieve your record based on scheme_code without repeating it and your desire results. :)
function show_last_updated_data() {
$query = $this->db->select('*')
->from('my_table')
->group_by('scheme_code')
->order_by('updated_on', 'DESC')
->get();
return $query->result();
}
As you have used custom date format, so the ordering will not work correctly until you convert the string to date format. Try this:
function show_last_updated_data(){
$this->db->select('*, str_to_date(updated_on, "%Y-%M-%d") date');
$this->db->from('my_table');
$this->db->order_by('date', 'DESC');
$query = $this->db->get();
return $query->result();
}
Note: It is recommended to use native date/datetime field, do not use custom formats. You can also go for UNIX timestamp and save it in an int field. As the date can be fetched in any format afterwards and will save you hassle like this one.
Related
I want to get all the datas that were created 30-365 days ago. Tried following codes but it's not working.
Database:
id created_at
1 2022-05-09
2 2021-06-08
Here id 2 was created before 365 days from today(2022-06-10), so it should not be shown. However id 1 was created before 30 days but not more than 365 days. So only id 1 should be shown.
Code 1:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
Output: it gives empty array
P.S if the 2nd where clause is commented, it gives both the ids and if the 1st where clause is commented, it gives id 1 only. But keeping both the condition gives empty array. What am I doing wrong?
Code 2:
$today = Carbon::now();
$doubtfulLoan = Loan::select('*')
->where([
['created_at', '<', $today->subDays(30)->endOfDay()],
['created_at', '>=', $today->subDays(365)->endOfDay()]
])->get();
Output: it gives both the array.
Thanks in advance.
You need to get into the habit of using CarbonImmutable to prevent nasty surprises like this. Use this code:
$today = CarbonImmutable::now();
$doubtfulLoan = Loan::select('*')
->where(function($query) use ($today) {
return $query
->where('created_at', '<', $today->subDays(30)->endOfDay())
->where('created_at', '>=', $today->subDays(365)->endOfDay());
})
->get();
This is because you are doing $today->subDays(30)->endOfDay() which changes the instance value of the carbon instance and then doing $today->subDays(365)->endOfDay() which changes it again. This is however the same instance, so the query builder will do:
SELECT * FROM loans WHERE created_at < '395 days ago' and created_at >= '395 days ago'
since you have passed the same instance. This obviously is never satisfied.
Using the CarbonImmutable class makes all your Carbon objects immutable and any modifications will create a new instance and will not modify the existing instance.
use laravel between method here
$doubtfulLoan = Loan::select('*')
->whereBetween('created_at',[
today()->subDays(365)->startOfDay(),
today()->subDays(30)->endOfDay()
])->get();
Hello please refer my following code which is in model
public function common_report($where) {
$this->db->select('*');
$this->db->from('collect_data_form_history_db as ch');
$this->db->join('board_artwork_history_db as bh','bh.shop_id = ch.shop_id');
$this->db->where('bh.shop_id', $where);
// $this->db->where('bh.shop_id',$where);
$query = $this->db->get();
return $query->result_array();
}
what i want is all data from both table collect_data_form_history_db and board_artwork_history_db.
I get the data but in the wrong format.
In table 'collect_data_form_history_db ' i have 11 entries and in board_artwork_history_db i have 18 entries.
so data I get should be 29 rows but I get 198 rows means 11 * 18.
please tell me the solution
You need to use left join for that. Try this way
$this->db->join('board_artwork_history_db as bh','bh.shop_id = ch.shop_id', 'left');
$this->db->select('t1.*, t2.*')
->from('collect_data_form_history_db t1, board_artwork_history_db t2')
->where('t1.shop_id = t2.shop_id')
->where('t2.shop_id', $where);
$query = $this->db->get();
Try full outer join
public function common_report($where) {
$this->db->select('*');
$this->db->from('collect_data_form_history_db as ch');
$this->db->join('board_artwork_history_db as bh','bh.shop_id = ch.shop_id', 'full outer');
$this->db->where('bh.shop_id', $where);
// $this->db->where('bh.shop_id',$where);
$query = $this->db->get();
return $query->result_array();
}
i wasnt able to retrive fields from Joomla from 2 tables , the problem is the query return always 3 result but should return 2 result
public function getAgent(){
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select(array('ag.company_id','ag.first_name','ag.last_name'));
$query->from('#__cddir_agent AS ag');
$query->join('INNER','#__cddir_company AS c ON ag.company_id = c.id');
$data = $db->setQuery($query);
$result = $db->loadObjectList();
return $result;
}
can anyone tell me where is my issue
thanks
The query returns 3 because you are asking it to return 3 column fields in the line:
$query->select(array('ag.company_id','ag.first_name','ag.last_name'));
If you want to return 2 fields then ask it to return 2 column fields like
$query->select(array('ag.first_name','ag.last_name'));
Suppose you have the following table values:
date | value
2012-01-01 | 8
2012-01-02 | 3
2012-01-03 | 17
2012-01-09 | 100
2012-01-12 | 2
Now suppose you want to select all the dates between 2012-01-02 and 2012-01-12 and show their values if present. If you simply query the table for the appropriate date range, the dates that don't have values are going to be absent, for obvious reasons. Is there a way to fill in those dates in the query?
The obvious solution is to create a table dates that just stores a list of all dates that may come up, and then to select from the dates table and join values to it, but I'd like to have a solution that doesn't rely on creating a single-column table if I can.
Of note: there are existing questions on SO on this topic, but they are all from 2010 (at least the ones I found when searching were), and MySQL features have grown in that time; there may be a dynamic solution now. If that's not the case, and the dates table is still the best solution, then this question should be closed as a duplicate.
The lack of answers from others suggests to me that at the current time, it is not possible to traverse a range of dates in MySQL without a table that holds those dates. I have, however, written some code in PHP that I'm using to fill in the missing dates after the fact:
function formatResults($inbound, $from, $to) {
$results = array();
$count = 0;
// In order not to lose any results, we have to change how the results are referenced
$indexes = array();
$stats = array();
foreach ($inbound as $stat) {
// ['listindex'] is the date, renamed in the query
$stats[$stat['listindex']] = $stat;
}
// In a function in case you want to pop it out
function dateArray($from, $to) {
$begin = new DateTime($from);
$end = new DateTime($to);
$interval = DateInterval::createFromDateString('1 day');
$days = new DatePeriod($begin, $interval, $end);
$baseArray = array();
foreach ($days as $day) {
$dateKey = $day->format("Y-m-d");
$baseArray[] = $dateKey;
}
$baseArray[] = $to;
return $baseArray;
}
$indexes = dateArray($from, $to);
// Now all the rows we need to return are uniquely identified in $indexes
// So we traverse $indexes to create our results array, rather than relying on $inbound
foreach($indexes as $index) if ($index != '') {
$data = array();
// Make sure we do not run into any 'missing index' problems
if (!isset($stats[$index]))
$stats[$index] = array(
'listindex' => $index,
// ... populate full list of empty fields
);
foreach ($stats[$index] as $key => $value) {
$data[] = $value;
}
$results[$count] = $data;
$count++;
}
return $results;
}
I'm currently using Zend Framework 2 and a query with date ranges to obtain data out of a MySQL DB, and I came across the between clause that was previously not available in ZF1.
However, my code which looks something like this is not working correctly:
$dateStart = '2012-12-20';
$dateEnd = '2012-12-31';
$sql = new Sql($_db);
$select = $sql->select()
->from(array("t" => $table))
->columns(array("col1" => "col_as_1", "col2" => "col_as_2"));
$select->where->between("date", $dateStart, $dateEnd);
$stmt = $sql->prepareStatementForSqlObject($select);
$result = $stmt->execute()->getResource()->fetchAll(\PDO::FETCH_ASSOC);
Apparently the between clause is not inclusive, I can only get results until 2012-12-30, is there a way to make it inclusive? I've been taking a look at the ZF2 docs but they are not very helpful and running the same query on MySQL query browser returns all of the data I need.
So you can try lessThanOrEqualTo and greaterThanOrEqualTo.
Between doesn't seem to provide this functionality: between($identifier, $minValue, $maxValue)
If you trace out your query with $select->__toString() you can see the query as string.
I don't have ZF2 on my computer but I could imagine that between in ZF2 will output date > '2012-12-20' AND date < '2012-12-31'.
NOTE THIS : WHEN USING between on Mysql
date_column_name between 'startDate' AND 'endDate'
NOTE : you should want to insert +1 date to endDate . Because of when you insert 2015-05-18 date to endDate.you can not get data of 2015-05-18.So you need to plus one date to endDate.
You can do it using this
$plusToDate = date('Y-m-d H:i:s', strtotime($toDate . ' + 1 day'));
The BETWEEN should be inclusive, are you sure there are no hours, minutes and seconds after the date, that would cause it not to select dates on 2012-12-31 since 2012-12-31 00:00:01 would technically be > 2012-12-31
Format must be same, use mysql DATE function
$select->where->between("DATE(date)", DATE('.$dateStart.'), DATE('.$dateEnd.'));
$from_date = date('Y-m-d', strtotime($AppCleaner->from_date ));
$to_date = date('Y-m-d', strtotime($AppCleaner->to_date ));
$select->where->between('appointment_date', $from_date . ' 00:00:00', $to_date . ' 23:59:59');
also, Use the between clause as below:
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->from('app_posts');
$select->where->NEST->between( 'id', 30,40);
$select->group('app_posts.id');
// echo $select->getSqlString($this->adapter->getPlatform());
// exit;
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
$resultSet = new ResultSet();
$resultSet->initialize($result);
$posts = $resultSet->buffer()->toArray();
return $resultSet;
Try this:
//I have a static function to make conversion Data Format
public static function convertBrazilianDate2MySQLDatabase($dataBrazil) {
$array = explode("/", $dataBrazil);
$array = array_reverse($array);
$str = implode($array, "/");
return date("Y-m-d", strtotime($str));
}
//In My Service I built my sentence
$dtStart = \Estrutura\Helpers\Data::convertBrazilianDate2MySQLDatabase($dt_start) . ' 00:00:01';
$dtEnd = \Estrutura\Helpers\Data::convertBrazilianDate2MySQLDatabase($dt_end) . ' 23:59:59';
$select->where->between('field name in table', $dtStart, $dtEnd);
[...]