Laravel where with 2 tables - php

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

Related

laravel select query create dynamic column name not working

I am trying Laravel join query to select the column dynamically but below line is returning error.
\DB::raw('table3.ElrA'.($effectiveYear'.-YEAR(table1.eff_date).'))
table3 having columns like this ElrA1, ElrA2 .....
common part is "ElrA" I am just making trailing number dynamically to create whole column name but it gives me err like "ElrA202-YEAR(table3.eff_date) is not a column". can you please suggest any solutions.
$query = DB::table('table1')
->join('table2', function($join) {
$join->on('table2.policy_period_id', '=', 'table1.id');
$join->where('status','1');
})
->leftjoin('table3', function($join) use($effective_date)
{
$join->on('table3.class_code', '=', 'table2.code');
$join->where('table3.date', '=', DB::raw("(select max(`date`) from table3 where date <= '".$effective_date."' limit 1)"));
})
->select(\DB::raw('table3.ElrA'.($effectiveYear'.-YEAR(table1.eff_date).')))
->where('table1.mod_id',$id);
Thanks
When you look at the error code, it says clearly that laravel try to find column ElrA202-YEAR(table3.eff_date)
What happen is because you make mistake in this part
'table3.ElrA'.($effectiveYear'.-YEAR(table1.eff_date).'
the exact part is in this one
'.-YEAR(table1.eff_date).'
because you use '' and it will parsed as string and not the variable that you want
I don't know why you will use dynamic column, but it is really not a good idea, because as the documentation says, it's very vulnerable with sql injection attack because there is no parameter binding in dynamic column. But if you know what you are doing then it's okay

Laravel Eloquent Where not working after joining table

Hi I have written a little query which doesnt seem to working when I use Eloquent but works when I write something similar in MySQL. Data isnt being retuned which shouldnt be due to my where clauses.
I have written this query which isnt working as expected -
$invoices = Invoice::leftJoin('user_details', 'invoices.user_id', 'user_details.user_id')
->where('invoices.practice_id', '!=', 'user_details.practice_id')
->first();
It is returning data where the invoice.practice_id = user_details.practice_id
I altered the query to prove it isnt working -
$invoices = Invoice::select('invoices.practice_id', 'user_details.practice_id')
->leftJoin('user_details', 'invoices.user_id', 'user_details.user_id')
->where('invoices.practice_id', '!=', 'user_details.practice_id')
->first();
The values returned the practice_id is 6, 6 which shouldnt be possible due to the following where clause where('invoices.practice_id', '!=', 'user_details.practice_id')
Have I done something wrong which I am just not seeing?
Thank you for any help you can provide!
UPDATE
Here is the DB schema for the invoice table
Here is the the DB schema fro the user_details table
The expected result is mentioned above, no results should be returned if invoice_practice_id = user_details.practice_id
#Luke Rayner
Try by rewriting line ->leftJoin('user_details', 'invoices.user_id', 'user_details.user_id')
to
->leftJoin('user_details', 'invoices.user_id', '=', 'user_details.user_id')
If not try to print Last query and post it

Prevent getting a duppicate data from the database in CodeIgniter

I'm trying to get data from the database filtered by some categories
This is my code in CodeIgniter
$this->db
->select('*')
->from($this->table)
->join('sites','sites.id = categories_by_site.site_id')
->where('categories_by_site.category_id', $categories[0])
->or_where('categories_by_site.category_id', $categories[1])
->order_by('id', 'ASC')
->get()
->result();
I simplify my code for the sake of this question, the above query take the categories as a search filter and used it to get result from the database.
There can be many categories filter to search at the same time, that's why I am using or_where() method.
The problem with this, when I got the result data, it has duplicate row of entries in object array.
Anyone can suggest how to prevent from getting a duppicate data from the database using above query?
Thanks
You can use group_by to solve this issue
Replace your code with
$this->db
->select('*')
->from($this->table)
->join('sites','sites.id = categories_by_site.site_id')
->where('categories_by_site.category_id', $categories[0])
->or_where('categories_by_site.category_id', $categories[1])
->order_by('id', 'ASC')
->group_by('categories_by_site.category_id')
->get()
->result();
You can eleminate duplicate values using distinct or group by
As you select all fields a group by is better in my opinion. Example to group by category_id
$this->db->group_by('category_id');

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.

Categories