I trying to use Laravel count() function to get the count of row. I have below code to count the number of row of 2 join table.
Example 1:
$row = DB::table('log_user_login')
->select(DB::raw('log_user_login.Password as LogPassword'), 'user.*')
->join('user', 'log_user_login.Username', '=', 'user.Username')
->where('log_user_login.LoginSession', '!=', '')
->groupBy('user.ID')
->get();
$count = sizeof($row);
Example 2:
$count = DB::table('log_user_login')
->select(DB::raw('log_user_login.Password as LogPassword'), 'user.*')
->join('user', 'log_user_login.Username', '=', 'user.Username')
->where('log_user_login.LoginSession', '!=', '')
->groupBy('user.ID')
->count();
When I echo $count form Example 1, the number of $count is 15415. But $count of Example 2 return me 89. May I know why this happen and how can I get the number of row without using the get()?
Example 1 displays the sizeof array in bytes, but example 2 displays total count returned by table.
So, best way to get total count is using ->count() as done in example 2.
Hope you got your answer.
Please try it.
$row = DB::table('log_user_login')
->select(DB::raw('log_user_login.Password as LogPassword'), 'user.*')
->join('user', 'log_user_login.Username', '=', 'user.Username')
->where('log_user_login.LoginSession', '!=', '')
->groupBy('user.ID')
->get();
echo $count = count($row);
Do not use sizeof(). So many time its return amount of memory allocated.
Use count() instead of sizeof().
Related
I have a user table and i am searching with 5 request parameter with multiple where like query.I want percentage of matched records in Laravel search query. Suppose for first user three search column matched , for second user 5 column matched then how can i get count or percentage of each user matched?
Please help me. I want to show the user matched % (Ex. User1-20% matched, User1-100% matched)
My Query
$searchJobSeeker = DB::table('users')
->join('job_seekers_details', 'job_seekers_details.user_id', '=', 'users.id')
->where('users.role', '=', 'job_seeker')
->where('job_seekers_details.position', 'like', '%'. $userDetails->companydetails->position .'%')
->orwhere('job_seekers_details.contract_length', 'like', '%'. $userDetails->companydetails->contract_length)
->orwhere('job_seekers_details.industry', 'like', '%'. $userDetails->companydetails->industry)
->orwhere('job_seekers_details.salary', '=', $userDetails->companydetails->salary)
->orwhere('job_seekers_details.willing_to_relocate', '=', $userDetails->companydetails->willing_to_relocate)
->distinct()
->get();
I would suggest adding foreach on your results, like this :
$matchRates = [];
foreach($searchJobSeeker as $seeker){
$rate = 0;
// All your rate calculations here, like the one below ...
$rate += Str::contains($seeker->position, $userDetails->companydetails->position) ? 20 : 0;
$matchRates[$seeker->id] = $rate;
}
Im new to this Framework, i dont know how to optimize it using db::raw count and aliases and display it to my blade.php using #foreach
im trying to optimize my code, my goals is to count pallet_conditions and store it to my aliases, i dont want to count it one by one like what i did on this code
this is my code not optimize:
//computing the total rapairable
$repairable_total = DB::table('liip_psrm_items')
->where('psrm_items_id', '=' , $psrm_maintenance->id)
->where('pallet_condition', '=', 1)
->count();
//REPAIRABLE
//computing the total good pallets
$good_total = DB::table('liip_psrm_items')
->where('psrm_items_id', '=' , $psrm_maintenance->id)
->where('pallet_condition', '=', 0)
->count();
//GOOD
this is the code, what i wanted to learn. just to minimize, and use aliases
$result = DB::table('liip_psrm_items')
->select(DB::raw('COUNT(liip_psrm_items.pallet_condition = 0 ) AS condition_1',
'COUNT(liip_psrm_items.pallet_condition = 1 ) AS condition_2'))
->where('psrm_items_id', '=' , $psrm_maintenance->id)
->get();
You can't use single query for two different results, which has totally opposite conditions.
Case 1. You are trying to count the items where pallet_condition = 1;
Case 2. You are trying to count the items where pallet_condition = 0;
Now you want to merge these two cases into single query, which is impossible...
So, For these two cases, you have to use either separate queries ( what you did already )
or you can use single query to grab all the items and then use PHP to separate them.
Like:
$total_items = DB::table('liip_psrm_items')
->where('psrm_items_id', '=' , $psrm_maintenance->id)
->get();
$repairable_count = count(array_filter($total_items, function($item){
return (bool)$item->pallet_condition;
}));
$good_count = count(array_filter($total_items, function($item){
return !(bool)$item->pallet_condition; //just inverse of the above condition
}));
i hope this might help.
To count at multiple condition I used this approach
$lastMonthInvoices = Invoice::select(DB::raw("(COUNT(*)) as count"), DB::raw('SUM(total) as total'),'status')
->whereDate('created_at', '>', Carbon::now()->subMonth())
->groupBy('status')
->get();
i got the result with groupBy Status and in each group total number of records as count & also their sum as total
these two snaps are of one query result
You can, first group by, then get count
Like :
DB::table('liip_psrm_items')
->groupBy('pallet_condition')
->select('pallet_condition', DB::raw('count(*) as total'))
->get();
Try to pass a closure like so:
$results = DB::table('liip_psrm_items')
->where('psrm_items_id', '=' , $psrm_maintenance->id)
->where(function($query){
$query->where('pallet_condition', 1)
->orWhere('pallet_condition', 0);
})->count();
I want to get the template from user_webhook table in my database.In WHERE condition i am checking user_id,app_id and if either notify_admin or notify_customer value is 1 in user_webhook table.I am using query..
$templates= $this->where('notify_admin',1)
->orwhere('notify_customer',1)
->where('user_webhooks.user_id',$user_id)
->where('user_webhooks.app_id',$app_id)
->select( 'webhooks.id as webhook_id','webhooks.app_id','webhooks.topic','webhooks.type','webhooks.action',
'webhooks.sms_template','user_webhooks.id','user_webhooks.notify_admin',
'user_webhooks.notify_customer','user_webhooks.user_id','user_webhooks.sms_template_status',
'user_webhooks.sms_template as sms'
)
->join ('webhooks',function($join){
$join>on('webhooks.id','=','user_webhooks.webhook_id');
})
->get()
->toArray();
when i get query using DB::getQueryLog(), I found the query seems Like
select `telhok_webhooks`.`id` as `webhook_id`, `telhok_webhooks`.`app_id`,
`telhok_webhooks`.`topic`, `telhok_webhooks`.`type`, `telhok_webhooks`.`action`,
`telhok_webhooks`.`sms_template`, `telhok_user_webhooks`.`id`,
`telhok_user_webhooks`.`notify_admin`, `telhok_user_webhooks`.`notify_customer`,
`telhok_user_webhooks`.`user_id`, `telhok_user_webhooks`.`sms_template_status`,
`telhok_user_webhooks`.`sms_template` as `sms` from `telhok_user_webhooks`
inner join
`telhok_webhooks` on `telhok_webhooks`.`id` = `telhok_user_webhooks`.`webhook_id`
where `notify_admin` = ? or `notify_customer` = ? and `telhok_user_webhooks`.`user_id`
= ? and `telhok_user_webhooks`.`app_id` = ?
The result of query giving result of all app_id and user_id.
So Please tell me use of OR in where condition.
Thanks in advance.
You may chain where constraints together as well as add or clauses to the query. The orWhere method accepts the same arguments as the where method:
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
Advanced usage:
Usere::where('id', 46)
->where('id', 2)
->where(function($q) {
$q->where('Cab', 2)
->orWhere('Cab', 4);
})
->get();
The whereIn method verifies that a given column's value is contained within the given array:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
More: https://laravel.com/docs/5.5/queries
Change
->where('notify_admin',1)
->orwhere('notify_customer',1)
to
->where(function($q){
$q->where('notify_admin',1)
->orWhere('notify_customer',1);
})
Without this, the orWhere will compare to all other wheres in your query instead of just comparing those two columns
I want to optimize my query I am executing with Laravel. I'm using MySQL for my project and I have a table named locations. It has more than 2 million records.
When I execute the code below it's too slow. How can I optimize my query to improve the speed?
foreach ($employees as $employee){
$percentage = 0;
if ($employee->position->zones->count() > 0) {
if($employee->position->zones->first()->workingzones->count() > 0) {
$workingZone = $employee->position->zones->first()->workingzones->last();
$tagCode = $employee->rfids->first()->rfid_id;
$zoneTime = DB::table('location')
->select(DB::raw('count(*) as count'))
->where('tagCode', $tagCode)
->where('xLocation', '>', $workingZone->x1)
->where('xLocation', '<', $workingZone->x3)
->where('yLocation', '>', $workingZone->y3)
->where('yLocation', '<', $workingZone->y1)
->where('locationDate', '>=',''.$currentDate.' 00:00:01')
->where('locationDate', '<=', $currentDate. ' 23:59:59')
->get();
$totalWorkedTime = DB::table('location')
->select(DB::raw('count(*) as count'))
->where('tagCode', $tagCode)
->where('locationDate', '>=',''.$currentDate.' 00:00:01')
->where('locationDate', '<=', $currentDate. ' 23:59:59')->get();
if ($zoneTime->first()->count == 0 || $totalWorkedTime->first()->count == 0) {
$percentage = 0;
}else {
$percentage = (int)ceil(($zoneTime->first()->count /12 )* 100 / ($totalWorkedTime->first()->count / 12));
}
}
}
$employee->percentage = $percentage;
}
You do a full ->get() twice and only use the ->first() result. When you just need 1, just use ->first() instead of ->get().
Also you can eagerload the position and zones while fetching the employees , and saving 2 additional queries per loop (- grouped eagerload queries on total), like this:
$employees = Employee::where(/*where foo here*/)
->with('position.zones')
->get();
And to consume less mem, chunk it.
Employee::where(/*where foo here*/)
->with('position.zones')
->chunk(200, function ($employees) {
foreach ($employees as $employee) {
// current code here with ->first() instead of ->get()
}
});
Adding indexes on the following columns should improve your performance:
xLocation
yLocation
locationDate
How to add indexes with an MySQL query:
https://dev.mysql.com/doc/refman/5.7/en/create-index.html
or if you use Laravel's migrations: https://laravel.com/docs/5.4/migrations#indexes
Edit:
Also: instead of doing the COUNT(*) on both select queries, use COUNT(`id`), so you don't count all columns, but only the id column
I am trying to get a result set from a laravel eloquent query whereby I match a column against a list of values in an array.
$authenticated_operation_ids = AccessControl::where('user_id', '=', $user_id)
->where('entity_type_id', '=', $operation_entity_id)
->pluck('entity_access_id')->toArray();
$authenticated_operations = Operation::whereIn('id', $authenticated_operation_ids);
return view('page.index')->withOperations($authenticated_operations);
You can try it as:
$authenticated_operation_ids = AccessControl::where('user_id', '=', $user_id)->where('entity_type_id', '=', $operation_entity_id)->pluck('entity_access_id')->toArray();
$authenticated_operations = Operation::whereIn('id', $authenticated_operation_ids)->get();
return view('page.index')->withOperations($authenticated_operations);
Add get() at the end of the query.
1) pluck returns a single value from a single row. You want lists to get a single column from multiple rows. toArray may not be needed, as it returns an array of values
$authenticated_operation_ids = AccessControl::where('user_id', '=', $user_id)
->where('entity_type_id', '=', $operation_entity_id)
->lists('entity_access_id');
2) You're forgetting to actually retrieve the rows in your second line:
$authenticated_operations = Operation::whereIn('id', $authenticated_operation_ids)
->get();
You have to call get() function on the result set to obtain results. The modified code will be like
$authenticated_operation_ids = AccessControl::where('user_id', '=', $user_id)->where('entity_type_id', '=', $operation_entity_id)->get()->pluck('entity_access_id');
$authenticated_operations = Operation::whereIn('id', $authenticated_operation_ids)->get();
return view('page.index')->withOperations($authenticated_operations);
or you can use a cursor to process it.