Laravel: WhereNull, OrWhere, is ignoring WhereRaw - php

In my controller I am using Laravels WhereNull, OrWhere and WhereRaw in DB Query. It is pulling in all the results but the problem is it looks like it is pulling in everything and ignoring the last Where clause. I have used this in a different method on other controllers and it works fine. Is there a specific order or something I am missing?
Doesn't Work (Ignores WhereRaw and shows all results)
$lists = DB::table('statuses')
->whereNull('company_id')
->orWhere('company_id', '=', Auth::user()->company_id)
->whereRaw("FIND_IN_SET('Task',assigned_to)")
->get();
This works in other controllers used as a different method without the whereRaw:
return Status::whereNull('company_id')->orWhere('company_id', '=', Auth::user()->company_id)
->orderBy('created_at', 'asc')
->get();
Sample DB
Source link: https://laravel.com/docs/5.3/queries#where-clauses

Use DB::raw instead of whereRaw
->where(DB::raw("FIND_IN_SET('Task',assigned_to)"))

Related

Laravel where with 2 tables

I'm trying to check the another table to remove the matches from the results but unable to figure this out.
$value = people::select(array('people.blog_id'))
->join('blocks', 'people.user_id', '=', 'blocks.blocker')
->where('people.user_id', $user->id)
->where('blocks.blocker', '!=', 'people.user_id')
->get()
->toArray();
What I am trying to achieve, is to strip away the results when getting user_id from people where blocker is found as well in the blocks table, but the following returns an empty array.
As per laravel doc
You may use the table method on the DB facade to begin a query. The table method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get method.
Change your query statement like bellow-
$articles = DB::table('people')
->join('blocks', 'people.user_id', '=', 'blocks.blocker')
->where('blocks.blocker', '<>', 'people.user_id')
->select('people.blog_id')
->get();
I think you should use right join here instead of simple join,
You can do it like.
$value = people::select(array('people.blog_id'))
->join('blocks', 'people.user_id', '=', 'blocks.blocker', 'right')
->where('people.user_id', $user->id)
->get()->toArray();
Please notice the fourth parameter in the join statement, this will include only the results where blocks will find.
Hope this will help

whereraw Vs DB::raw in Laravel

I am confused and really don't know how and where should I choose to use one from both ?
I read docs for both
https://laravel.com/docs/5.4/queries#where-clauses
And
https://laravel.com/docs/5.4/queries#raw-expressions
If I use query something like this its not working
DB::table('table_name')
->where('parent_id', $parent_id)
->whereRaw("date",">",$date)
->get();
But it works
DB::table('table_name')
->where('parent_id', $parent_id)
->where(DB::raw("date",">",$date))
->get();
DB::raw() lets you write raw statements as a part of the query. Eg:
->where(DB::raw('DATE(date_column)'), '>', '2017-01-01')
But if you need to write a complete "raw where", you should use whereRaw (for your convenience). Eg:
->whereRaw('DATE(date_column) > DATE(another_date_column)')
Also, whereRaw() accepts a complete where clause.
So, in your first example it's not working, because you should do it:
->whereRaw("date > ".$date)
And your second example could be simplified by using just whereRaw() like the above statement in my answer.
Also DB::raw() can be used in ->select(),groupBy() and others.

Laravel 4 unable to join on multiple conditions using ->on( ) more than once

In a nutshell I am trying to do a join with more than one condition. We are using legacy Laravel 4, and the actual class I've tracked it to is Illuminate\Database\Query\Builder. Here is what I am adding:
->leftJoin('node_fields AS visible_for_categories', function($join){
$join->on('nv2.id', '=', 'visible_for_categories.node_version_id');
$join->on('visible_for_categories.name', '=', 'visible_for_categories');
})
It works fine with the first $join->on( ) call, but the page fails if the second on is called. why is this and what is the proper way to do this in Laravel 4?
The way that worked for me on the above query is as follows:
->leftJoin('node_fields AS visible_for_categories', function($join){
$join->on('nv2.id', '=', 'visible_for_categories.node_version_id');
$join->on('visible_for_categories.name', '=', DB::raw("'visible_for_categories'"));
})
The query builder will assume all three values in the on() function are fields, not strings, and will parse out the . period as well.
The general assumption is that JOINS will have the relational field joins to create structure, and the WHERE conditionals will provide the desired filter. However anyone who's worked esp. with LEFT or RIGHT joins knows this is not always possible.
Be careful for SQL injection using DB::raw but in this case, an EAV table, we're dealing with a fixed string, not a variable.
Try
->leftJoin('node_fields AS visible_for_categories', function($join){
$join->on('nv2.id', '=', 'visible_for_categories.node_version_id')
->on('visible_for_categories.name', '=', 'visible_for_categories');
})

Only get the first row while doing a leftjoin

Is it possible to limit the result while doing a leftjoin?
(Laravel 4.2) - Querybuilder
I've got the following query with laravel's querybuilder:
DB::table('part')
->leftjoin('model', 'model.model_id', '=', 'part.model_id')
->leftjoin('make', 'model.make_id', '=', 'make.make_id')
->leftJoin('photo', 'photo.part_id', '=', 'part.part_id')
->select( 'part.part_id',
'part.model_id',
'make.desc as make_desc',
'model.desc as model_desc',
'photo.local as local_img',
'photo.cdn as cdn_img')
->take(8)->get();
Every part has more then 4 photos, but i only want the first photo to be included in the join. The problem is that when i use this query, i get 8 part objects (results). But the 8 results are not 8 parts, but 2 parts. This query creates 4 of the same part objects, with the only difference being the photo (the join includes every photo).
I tried things like:
->select( '(photo.local LIMIT 1) as local_img',
'(photo.cdn LIMIT 1) as cdn_img')
But this doesn't work. I also tried to do raw query's. Also i tried to use the '->take(1)' in a leftjoin closure, like this:
->leftjoin('photo', function($q){
$q->on('photo', 'photo.part_id', '=', 'part.part_id')->take(1);
});
But this is not possible.
I`m searching for a solution to only include the first photo row in a leftjoin.
Edit: Following up on mgrueter's answer. I know that a groupby would do the trick, but this makes the query very slow. So i want to do it in a different way so the query doesn't get to slow.
Group the results by 'part.id':
DB::table('part')
->leftjoin('model', 'model.model_id', '=', 'part.model_id')
->leftjoin('make', 'model.make_id', '=', 'make.make_id')
->leftJoin('photo', 'photo.part_id', '=', 'part.part_id')
->select( 'part.part_id',
'part.model_id',
'make.desc as make_desc',
'model.desc as model_desc',
'photo.local as local_img',
'photo.cdn as cdn_img')
->group_by('part.part_id')
->take(8)->get();
And also order the results by 'photo.created' or whatever column you have to determine, which is the first photo.

Laravel query with joins, same name in multiple tables

I have a large query. For all intents and purposes, I'll recreate the issue using a smaller query as an example:
DB::table('cases')
->join('contacts', 'cases.id', '=', 'contacts.id')
->select('cases.name', 'contacts.name')
->get();
And then in laravel's templating (Blade) when I do a foreach loop and print the results, it's printing the results from the cases table for {{ $case->name }}
I understand the problem and why it is happening, but how can I make it work properly?
This is a PDO restriction and has nothing to do with laravel. If you need them both, you'll have to alias it in your query:
DB::table('cases')
->join('contacts', 'cases.id', '=', 'contacts.id')
->selectRaw('cases.name as cases_name, contacts.name as contacts_name')
->get();

Categories