Laravel: where condition based on db field - php

How to make a whereclause that is based on an existing field in the database, and not on an input parameter?
$query = DB::table('events')
->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id');
$join->where('events_dates.start_date', "<=", $data['date_end']);
$join->where('events_dates.end_date', '>=', $data['date_start']);
});
This works well because the where clause is based on an input parameter.
What I need is a Where clause that is based on a field that is already in the database:
Something like this:
$query = DB::table('events')
->join('events_dates', function($join) use ($data){
$join->on('events.id', '=', 'events_dates.event_id');
//If db field of record: recurrent == 0 then
$join->where('events_dates.start_date', "<=", $data['date_end']);
$join->where('events_dates.end_date', '>=', $data['date_start']);
/* If db field of record: "recurrent" == "1" then
$join->where //another query
*/
});
Is this achievable with the laravel ORM, or should I write a native SQL query?
Haven't found a suitable answer in the docs or in existing posts.

You need to use...
where('column1', '=', DB::raw('column2'));
...to use the field value instead of the string "column2".
In this answer I further explained why.

Related

How to add a where clause when using "with" on an Eloquent query in Laravel

I have a query built where I'm using "with" to include related models. However, I'm not sure how to filter those related models in a where clause.
return \App\Project::with("projectLeaders")->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
Please note the with("projectLeaders") in the query. So, ProjectLeaders is a relation that brings objects of kind Employee, how can I filter in that query those "Employees" whose attribute "Lastname" is like "Smith" ?
You can implement where class both tables. Please check following code and comments.
return \App\Proyecto::with(["projectLeaders" => function($query){
$query->where() //if condition with inner table.
}])->join('empresas', 'id_empresa', '=', 'empresas.id')
->join('tipo_estado_proyecto', 'tipo_estado_proyecto.id', '=', 'proyectos.id_tipo_estado_proyecto')
->where() //if condition with main table column.
->select('empresas.*', 'tipo_estado_proyecto.nombre AS nombreEstadoProyecto', 'proyectos.*');
You can use Closure when accessing relation using with. Check below code for more details:
return \App\Project::with(["projectLeaders" => function($query){
$query->where('Lastname', 'Smith') //check lastname
}])->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
You may use the where method on a query builder instance to add where clauses to the query. The most basic call to where requires three arguments. The first argument is the name of the column. The second argument is an operator, which can be any of the database's supported operators. Finally, the third argument is the value to evaluate against the column.
return \App\Project::with("projectLeaders")->join('companies', 'company_id', '=', 'companies.id')
->join('project_status', 'project_status.id', '=', 'projects.status_id')
->where('lastname','=','Smith')
->select('companies.*', 'project_status.name AS statusName', 'projects.*');
Don't forget to return results with a get();
The query you have written is correct. But after building the query you need to fetch the data from database.
METHOD ONE
So adding get() method to your query:
return App\Project::with('projectLeaders')
->leftJoin('companies', 'company_id', '=', 'companies.id')
->leftJoin('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*')
->get();
METHOD TWO (with pagination)
return App\Project::with('projectLeaders')
->leftJoin('companies', 'company_id', '=', 'companies.id')
->leftJoin('project_status', 'project_status.id', '=', 'projects.status_id')
->select('companies.*', 'project_status.name AS statusName', 'projects.*')
->paginate(3);

Laravel Model Using Or in where Condition?

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

Laravel Condition Query Not Working

My Requirements : I select baseleads table with Random Order using following conditions
beaseleads currentstatus column value have New Lead Status or
beaseleads currentstatus column value have Call Not Picking status and updated_at date is not Equal to Today Date.
My Laravel Query is below
$baseleadsData=Baseleads::inRandomOrder()->Where('process_status',0)->where(function ($query) {
$query->where('current_status','New Lead');
$query->Orwhere('current_status','Call Not Picking');
$query->OrwhereDate('updated_at', '!=', date('Y-m-d'));
})->first();
Its not Working Properly. What is my Mistake.
->where(function ($query) {
$query->where('current_status','New Lead')
->orWhere('current_status','Call Not Picking')
->orWhere('updated_at', '!=', date('Y-m-d').' 00:00:00');})->first();
It's been a while since I used Laravel, but have you tried
$query->where('current_status', '=', 'New Lead');
$query->Orwhere('current_status', '=', 'Call Not Picking');
instead of
$query->where('current_status','New Lead');
$query->Orwhere('current_status','Call Not Picking');
I'm not sure this will work as it looks like Laravel automatically makes the comparison. What is the error code youre getting? (You can turn debug mode on in your settings file)
you need to use method names in camelCase
use orWhere and orWhereDate
You did mistake of method name, use Orwhere to orWhere, OrwhereDate to orWhereDate and Where to where. and orWhereDate outside of where query.
$baseleadsData=Baseleads::inRandomOrder()
->where('process_status',0)
->where(function ($query) {
$query->where('current_status','New Lead');
$query->orWhere('current_status','Call Not Picking');
})
->orWhereDate('updated_at', '!=', date('Y-m-d'))
->first();

Add the orderBy if the Request::get('xyz') field exist

In following pagination query i added the sorting code with OrderBy method but gives an error on first time page reload because there is no sort and order field is set there. how can i condition it set if exist or set null or else.
->select(array(
'to_jobs.rec_id',
'to_jobs.contarct_code',
'to_jobs.job_num',
'to_sites.site_name',
'to_sites.postcode',
'to_sites.site_id'
))
->orderBy(Request::get('sort'), Request::get('order'))
->leftjoin('to_sites', 'to_jobs.fk_site_id', '=', 'to_sites.site_id')
->paginate(10);
If you're using Eloquent, you can use local scope.
For query builder query, you can try to use when():
->when(request()->has('sort'), function ($q) {
return $q->orderBy(request()->sort, request()->order);
})
You can simply use if statement to check sort input and then build your pagination.
Try this.
$query->select(array(
'to_jobs.rec_id',
'to_jobs.contarct_code',
'to_jobs.job_num',
'to_sites.site_name',
'to_sites.postcode',
'to_sites.site_id'
))
->leftjoin('to_sites', 'to_jobs.fk_site_id', '=', 'to_sites.site_id');
if (Request::has('sort'))
{
$query->orderBy(Request::get('sort'), Request::get('order'));
}
$query->paginate(10);
Reference:
Condition based query in laravel

laravel elequent query with multiple conditions based on user search/filter

I am trying to retrieve all rows in my table, but with user filters(where conditions).
Table looks like this:
news: id, category, type, body, is_active
I want the user to filter them by: type and is_active
So i am using
if(Input::get("is_active"))
News::where("is_active", 1)->get();
if(Input::get("type"))
News::where("type", Input::get("type"))->get();
if(Input::get("category"))
News::where("category", Input::get("category"))->get();
How can I run all conditions on the same query? I don't want to make if/else for each condition and re-write the query all over again!
This way:
$query = News::newQuery();
if(Input::get("is_active"))
$query->where("is_active", 1)->get();
if(Input::get("type"))
$query->where("type", Input::get("type"))->get();
if(Input::get("category"))
$query->where("category", Input::get("category"))->get();
return $query->get();
You can pass a closure to where()
Try this:
$filters = ['is_avtive', 'type', 'category'];
News::where(function($q) use ($filters){
foreach($filters as $field)
$q->where($field, Input::get($field));
})->get();
Try this
News::where("is_active", 1)
->where('type', Input::get("type"))
->where('category', Input::get("category"))
->get();
or if you want only active news with other or conditions.
News::where("is_active", 1)
->orWhere(function($query)
{
$query->where('type', Input::get("type"))
->where('category', Input::get("category"))
})->get();
Check out advanced where

Categories