Very slow eloquent query - php

I have a query in one of my controller in my Laravel controllers that looks like this,
$project = new Project;
$me = ResourceServer::getOwnerId();
$my_projects = Project::ManagedByMe($me)
->OwnedByOrganisationIAmIn($me)
->IAmACollaborator($me)
->NoArchived()
->get(array(
'projects.id',
'projects.name',
'projects.description',
'projects.total_cost',
'projects.sales_person',
'projects.slug',
'projects.uri_hash',
'projects.client_id',
'projects.start_date',
'projects.finish_date',
'projects.organisation_id',
'projects.locked_by',
'projects.created_at',
'projects.status',
'projects.owner_id',
'projects.user_id',
'projects.archived_at'
));
$my_projects->load('projectmanager');
$my_projects->load('clients');
$my_projects->load('organisations')->load('organisations.users');
$my_projects->load('collaborators');
$my_projects->load('status');
$my_projects->load('notifications')->load('notifications.user');
$my_projects->load(array('projectview'=>function($query){
$query->where('users.id','=',ResourceServer::getOwnerId());
})); 
It returns 898 rows of data, and takes over a minute to execute. I am using scopes in the query, that look like this,
public function scopeManagedByMe($query, $user_id) {
$query->distinct();
$query->leftJoin('project_managers', 'projects.id', '=', 'project_managers.project_id');
$query->where('project_managers.user_id', '=', $user_id);
}
public function scopeOwnedByOrganisationIAmIn($query, $user_id) {
$query->leftJoin('organisations', 'projects.organisation_id', '=', 'organisations.id');
$query->leftJoin('organisation_user', 'organisations.id', '=', 'organisation_user.organisation_id');
$query->orWhere('organisation_user.user_id', '=', $user_id);
}
public function scopeIAmACollaborator($query, $user_id) {
$query->leftJoin('collaborators', 'projects.id', '=', 'collaborators.project_id');
$query->orWhere('collaborators.user_id', '=', $user_id);
}
public function scopeNoArchived($query) {
$query->orWhere('projects.archived_at', '=', '0000-00-00 00:00:00');
$query->whereNull('projects.deleted_at');
}
and the SQL that is actually run looks like this,
select distinct `projects`.`id`,
`projects`.`name`,
`projects`.`description`,
`projects`.`total_cost`,
`projects`.`sales_person`,
`projects`.`slug`, `projects`.`uri_hash`,
`projects`.`client_id`,
`projects`.`start_date`, `projects`.`finish_date`,
`projects`.`organisation_id`,
`projects`.`locked_by`, `projects`.`created_at`,
`projects`.`status`,
`projects`.`owner_id`,
`projects`.`user_id`,
`projects`.`archived_at`
from `projects`
left join `project_managers` on `projects`.`id` = `project_managers`.`project_id`
left join `organisations` on `projects`.`organisation_id` = `organisations`.`id`
left join `organisation_user` on `organisations`.`id` = `organisation_user`.`organisation_id`
left join `collaborators` on `projects`.`id` = `collaborators`.`project_id`
where `projects`.`deleted_at` is null
and `project_managers`.`user_id` = ? or `organisation_user`.`user_id` = ?
or `collaborators`.`user_id` = ? or `projects`.`archived_at` = ?
and `projects`.`deleted_at` is null
What I am trying to do, is select all the projects that I belong to, either by virtue that I am in an organisation that owns a project, I am project manager of the project or a collaborator of the project.

At first set indexes on join-condition fields:
`projects`.`id`
`projects`.`organisation_id`
`project_managers`.`project_id`
`organisations`.`id`
`organisation_user`.`organisation_id`
`collaborators`.`project_id`
if some of them are not setted.
Then update your query execution time in question subject.

Related

How to get the not applied jobs in the job table laravel

$joblist = JobDetail::join('candidates', 'job_details.id', '=', 'candidates.job_detail_id')
->where('candidates.user_id', Auth::id())
->where('candidates.job_detail_id', null)
->get();
SELECT job_details.*
FROM job_details
LEFT JOIN candidates
ON job_details.id = candidates.job_detail_id
WHERE candidates.job_detail_id IS NULL AND candidates.user_id = Auth::id()
This SQL query is not working.
I want to get the jobs that user didn't apply
jobs and users mapping table - candidate table
job details table
Consider fetching jobList from the candidate table :
$joblist = candidates::leftjoin('JobDetail','candidates.job_detail_id','job_details.id')
->where('candidates.user_id',Auth::id())
->whereNull('job_detail_id')
->select('job_details.*')->get();
------------job details model---------------
public function candidates(){
return $this->hasMany(candidate::class);
}
------------controller logic---------------
$userId = Auth::id();
$joblist = JobDetail:: whereDoesntHave('candidates', function ($query) use ($userId){
$query->where('user_id', $userId);
})->select('job_details.*')->get();

SQLSTATE[23000]: Integrity constraint violation: 1052. Laravel eloquent issue when joining table

I have News table and the column in the blade table posted by is empty but in my news table the column users_id which is the posted by has a users_id value. I cant get the user who posted the specific news in specific school. I already have a working query for the news, but the problem is i cant join the users table where the name of the user who posted the news is in there. Can someone know what are the problem of my query? Help will be appreciated. Thanks
Index controller
public function index()
{
//testing query that returns an error
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', Auth::user()->school_id)->get();
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = 'Auth::user()->school_id'");
//working queries and i dont know how to convert the $postedby query join to eloquent.
if (Auth::user()->role == 0) {
$news = Newsboard::where('active','=',1)->get();
} elseif (Auth::user()->role == 1 || Auth::user()->role == 5) {
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('active','=',1)
->get();
} else {
$role = Auth::user()->role;
$news = Newsboard::where('school_id', '=', Auth::user()->school_id )
->where('status', '=', 1)
->where('active','=',1)
->whereRaw("group_id in('$role', '0')")
->get();
}
dd($userschool);
return view('admin.pages.news.index', [
'page_title' => $this->page_title,
'news' => $news,
'mnuname' => 'News',
]);
}
Set your Auth::user()->school_id as variable
$school_id = Auth::user()->school_id;
//the query that i want still returns an error because of the auth
$postedby = DB::select(
"SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '$school_id'");
Or this:
Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where(['news.school_id' => $school_id])->get();
Because both users and news table contain school_id column, so in where condition must has table prefix.
Please try:
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('news.school_id', Auth::user()->school_id)->get();
//or
//the query that i want still returns an error because of the auth
$postedby = DB::select("SELECT news.*, users.name as postedby from news
JOIN users on news.users_id = users.id
WHERE news.school_id AND news.active = 1 AND news.school_id = '".Auth::user()->school_id."'");
$school_id = Auth::user()->school_id;
$userschool = Newsboard::select('users.name', 'news.school_id')
->join('users', 'users.id', '=', 'news.users_id')
->where('school_id', $school_id)->get();

Laravel eloquent query and join on OR condition

I am trying to do an eloquent query where it joins on a table where column a = x OR column b = x; and I cannot get it to work. So I am hoping that someone can help.
Here is my query:
$candidates = HrCandidate::where('people_id', '<>', 'NULL')
->with('contact')
->join(
'people',
->where('id','people_id')
->orWhere('alternate_id','people_id')
)
->get();
I am trying to join with the people table but where people_id = 1 or the alternate_id column. So I am hoping someone can help with this.
To get started, pass a Closure as the second argument into the join method. The Closure will receive a JoinClause object which allows you to specify constraints on the join clause:
$candidates = HrCandidate::join('people', function ($join) {
$join
->on('people.id', '=', 'candidates.people_id')
->orOn('people.alternate_id', '=', 'candidates.people_id');
})
->where('people_id', '<>', 'NULL')
->get();

How to use where not between in Laravel 5.5?

I am try
ing to get something like this
select * from `users`
inner join `settings`
on `users`.`id` = `settings`.`user_id`
and NOW() NOT BETWEEN quit_hour_start AND quit_hour_end
where `notification_key` != ''
and `device_type` = 'Android'
in eloquent. Does anyone try and get success to build this query in eloquent.
I know I can use \DB::select(DB::raw()); and get my result. But I want to use ie with Laravel eloquent method.
====== update comment for tried queries========
$androidUser = User::join('settings', function ($join) {
$join->on('users.id', '=', 'settings.user_id')
->where(DB::raw("'$currentTime' NOT BETWEEN quit_hour_start AND quit_hour_end"));
})
->where('notification_key', '!=', '')
->where('device_type' ,'=', 'Android')
->get();
$users = DB::table('users')
->whereNotBetween('votes', [1, 100]) // For one column
->whereRaw("? NOT BETWEEN quit_hour_start AND quit_hour_end", [$currentTime]) // Use whereRaw for two columns
->get();
https://laravel.com/docs/5.5/queries, or you can rewrite as to wheres

Convert mysql query into Eloquent laravel query

I am trying to make the following query in laravel:
SELECT a.name AS subname, a.area_id, b.name, u. id, u.lawyer_id,u.active_search,
FROM subarea a
LEFT JOIN user_subarea u ON u.subarea_id = a.id
AND u.user_id = ?
LEFT JOIN branch b ON a.area_id = b.id
The idea is to obtain the subareas and see if the search is activated by the user.
The user_subarea table might have a record that matches the id of the subarea table where the active_search is equal to 0 or 1. If it doesn't exist I would like the query to return null.
While I was able to achieve this in raw SQL when I try the same with eloquent in Laravel I am not returning any value. I have done the following:
$query = DB::table('subarea')
->join('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Any help will be much appreciated.
I found by myself the answer it was just to add a lefjoin in the first join. It is not in the laravel docs but works too.
$query = DB::table('subarea')
->lefjoin('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Try this one, If you get a problem, please comment.
$value = \Auth::user()->id;
$query = DB::table('subarea')
->where('user_subarea.user_id', '=',$value)
->leftJoin('user_subarea', 'subarea.id', '=', 'user_subarea.subarea_id')
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('subarea.name AS subname','subarea.area_id', 'branch.name', 'user_subarea.id','user_subarea.lawyer_id','user_subarea.active_search')
->get();

Categories