Putting orderby from highest to lowest in database query - php

1.I've a confusion on how to add sort orderby(highest to lowest) in my database query for the age.I've tried some few codes but it generates an error.Any help here is much appreciated.
public function ListOrgaScholar($ship_id){
$ship = Scholarship::find($ship_id);
$ship_age_from = $ship->ship_age_from;
$ship_age_to = $ship->ship_age_to;
$scholars = (new Scholar)->newQuery()->select('*');
$scholars->whereBetween(DB::raw('TIMESTAMPDIFF(YEAR,scholars.scholar_birthday,CURDATE())'),array($ship_age_from,$ship_age_to));
$scholars = $scholars->get();
}
2.Same us here.How to add orderby(highest to lowest) since it is two different where clause.The $ship_gpa_from and $ship_gpa_to are inputs of grade.
public function ListOrgaScholar($ship_id){
$ship = Scholarship::find($ship_id);
$ship_gpa_from = $ship->ship_gpa_from;
$ship_gpa_to = $ship->ship_gpa_to;
$scholars = (new Scholar)->newQuery()->select('*');
if($ship_gpa_from)
$scholars->where('scholar_GPA', '>=', $ship_gpa_from);
if($ship_gpa_to)
$scholars->where('scholar_GPA', '<=', $ship_gpa_to);
$scholars = $scholars->get();
}

Have you tried returning the results as collection and then applying collection functions on them? The code would look somewhat like this:
$scholarship = Scholarship::find($id);
$scholars = Scholar::all();
$selectedScholars = $scholars->filter(function ($item, $key) {
$scholarAge = Carbon::now() - $item->scholar_birthday //this depends on the value of scholar_birthday;
return ($scholarAge >= $scholarship->ship_age_from && $scholarAge <= $scholarship->ship_age_from);
})->sortBy("scholar_birthday");

Related

Laravel Problem: Please check why this code behave like this?

$sallery_min = 4000;
$sallery_max = 30000;
$job = Job::where('status', 1);
if ($sallery_min && $sallery_max) {
$job->whereIn('salary_level', $sallery_level);
}
$data = $job->orderBy('id', 'desc')->get();
dd($data);
when use above mention code then i got 7 result its working fine. But when i change in this code like this then 11 result come from database.can i do not do code like this. what happen when Job::where('status', 1); change into $job = new Job(); $job->where('status', 1);. why result come diffrent
$sallery_min = 4000;
$sallery_max = 30000;
$job = new Job();
$job->where('status', 1);
if ($sallery_min && $sallery_max) {
$job->whereIn('salary_level', $sallery_level);
}
$data=$job->orderBy('id', 'desc')->get();
dd($data);
in your code you are getting the result where status is 1 1 from your database by using this query
$job = Job::where('status', 1);
but you are not retriving the objects because you dont use get() or first().WHer first() is use for retrieving single row and get() is use for multipe row. So for retrieving teh expected result you have to use get() method like this.
$jobs = Job::where('status', 1)->get();
If you want to query the database with a new Job object, you should use the method chaining, like:
$job = new Job();
$jobs = $job->where('status', 1)
->when($sallery_min && $sallery_max, function ($q) use ($sallery_min, $sallery_max) {
return $q->whereBetween('salary_level', [$sallery_min, $sallery_max]);
})->get();
dd($jobs);
However, Eloquent provides the static method for convenience. Use it unless you have a specific reason to stick on with the new Object word around.
Extra Note:
The above code uses Conditional Where Clauses which avoids if ... else ... statements.

How use with() when also joining a table

I have the following tables (with only relevant fields):
devices
id
name
created_at
updated_at
device_reports
id
device_id
location
created_at
updated_at
I have a report with a number of filters on it that is already working, so I want to stick with the eloquent way of doing things. Here is Controller function:
public function devices(Request $request)
{
$devicesQuery = Device::with(['latestReport']);
if ($request->ajax())
{
if($request->input('start') && $request->input('start')!='')
{
$start_date = date('Y-m-d', strtotime($request->input('start')));
$end_date = date('Y-m-d', strtotime($request->input('end')));
$devicesQuery = $devicesQuery->lastReportBetween($start_date,$end_date);
}
$devices = $devicesQuery->paginate(10);
return Response::json(View::make('devices/table', array('devices' => $devices))->render());
}
}
The model's latestReport is defined as:
public function latestReport()
{
return $this->hasOne('App\Models\DeviceReport')->latest();
}
The model's function lastReportBetween is defined as:
public function scopeLastReportBetween($query, $start, $end)
{
$query = $query->join('device_reports AS dr', 'dr.device_id', '=', 'devices.id');
$query = $query->where('dr.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = devices.id)'));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '>=', DB::raw("STR_TO_DATE('".$start."', '%Y-%m-%d')"));
$query = $query->where(DB::raw("(IFNULL(dr.gps_time, dr.created_at))"), '<=', DB::raw("STR_TO_DATE('".$end."', '%Y-%m-%d')"));
return $query;
}
When running the above with a start/end date selected, I get the correct records returned, but I don't get anything returned in "latestReport", but when I run the page without the date filters in place, it correctly returns the device information and the most recent report record in the latestReport class variable.
Can anyone help me understand how to change this code such that I do get the latestReport back when I also call the lastReportBetween function?
I figured out my problem. I should have been using "whereHas()" instead of manual joins and whatnot.
public function scopeLastReportBetween($query, $start, $end)
{
return $query->whereHas('latestReport', function($reportsQuery) use ($start, $end)
{
$reportsQuery->whereBetween('created_at', [$start, $end])
->where('device_reports.id', '=', DB::raw('(SELECT max(dr2.id) FROM device_reports AS dr2 WHERE dr2.device_id = device_reports.device_id)'));
});
}

The wrong record in my database is getting updated

im using laravel eloquent to update a record in a database table. Im passing in a parameter of 52 which is the id of the record I want to update (primary key).
I am printing the query to check which record its finding and its printing the record with the id of 13 and then when i check the table, id 13 has been updated.
protected $connection = 'sqlsrv';
protected $table = 'todo';
public $timestamps = false;
public static function complete($todoId, $userId)
{
$now = new DateTime();
$query = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->find(52);
$query->where(function ($query) use ($now)
{
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
});
if ($query)
{
$query->completedDate = $now;
$query->save();
}
}
How about trying like this?
The query after using find did not make any sense since find returns the first object not a query builder instance.
public static function complete($todoId, $userId)
{
$now = new DateTime();
$object = Self::join('todoTypes', 'todo.typeId', 'todoTypes.id')
->where('todoTypes.canComplete', 1)
->whereNull('todo.completedDate')
->where(function ($query) use ($now) {
$query->whereNull('cancelDate')
->orWhere('cancelDate', '>', $now);
})->find(52);
if ($object) {
$object->completedDate = $now;
$object->save();
}
}
I have managed to fix this by just adding a select at the start
select('todo.id', 'todo.completedDate')
It seems it was getting the right row, but displaying the id as something else.
When I took out the join and the joins where clause, it worked. I suspect it was using the id of the joint row from the todoTypes table as that was 13.

Reusing a Yii2 query

Am trying to reuse a query but it fails.
In my method I have:
public function getPacked($from, $to){
$initquery = RealTimeTblTrucks::find()
->leftJoin('tbl_truck_history','tbl_truck_history.truck_id=tbl_trucks.id')
->where(["between","tbl_truck_history.created_at",$from,$to])
->andWhere(["tbl_truck_history.status"=>20]);
$data = [];
$data[SELF] =$initquery
->andWhere(["tbl_trucks.truck_category"=>28])
->count();
$data[NORMAL] = $initquery->andWhere(["tbl_trucks.truck_category"=>27])
->count();
$data[BULKER] = $initquery->andWhere(['in', 'tbl_trucks.truck_category', [26,34]])
->count();
return $data;
}
Now the first ($data[SELF]) returns the correct information but the next ones NORMAL and BULKER didn't return the correct information.
When I check on the raw query I can see that the last two are affected by the first one such that the new query at $data[NORMAL] contains a check for truck_category = 20 which should only be executed on the first array item (SELF).
How to refactor this to make it work?
Advantage of clone over creation a new object, is that, all properties will be copied into the new object instead of resetting them. This is quite useful when you use query builder.
public function getPacked($from, $to) {
$initquery = RealTimeTblTrucks::find()
->leftJoin('tbl_truck_history','tbl_truck_history.truck_id=tbl_trucks.id')
->where(["between","tbl_truck_history.created_at",$from,$to])
->andWhere(["tbl_truck_history.status"=>20]);
$data = [];
$querySelf = clone $initquery;
$data[SELF] = $querySelf
->andWhere(["tbl_trucks.truck_category"=>28])
->count();
$queryNormal = clone $initquery;
$data[NORMAL] = $queryNormal->andWhere(["tbl_trucks.truck_category"=>27])
->count();
$queryBulker = clone $initquery;
$data[BULKER] = $queryBulker->andWhere(['in', 'tbl_trucks.truck_category', [26,34]])
->count();
return $data;
}
Refer Yii2 clone detail

Laravel eloquent where returns result only for first element in foreach?

I'm having a simple hasMany relation between order and orderItems. What I'm trying to do is fetch the count of similar order items. This is what I've done:
$orderItems = $order->orderItems();
$distinctItems = $orderItems->groupBy('item_name')->distinct('item_name')->get();
foreach($distinctItems as $i){
$i['count'] = $orderItems->where('item_name', '=', $i->item_name)->count();
}
$order['items'] = $distinctItems;
However the count is returned for only first order Item and 0 for other items. I'm not sure why this is happening. I've also checked that where() returns null for the items except the first one.
Thanks for the help.
try using the collection only, first groupBy item_name and then on each item add count and return new collection which would look something like
$orderItems = $order->orderItems()->get();
$order['items'] = $orderItems->groupBy('item_name')->map(function($item) {
$i = $item->first();
$i->count = $item->count();
return $i;
});
Try this code.
$cnt = array();
foreach($distinctItems as $i){
$cnt[$i]['count'] = $orderItems->where('item_name', '=', $i->item_name)->count();
}
print_r($cnt);

Categories