83

I have a question about inner joins with multiple on values. I did build my code like this in laravel.

public function scopeShops($query) {
    return $query->join('kg_shops', function($join)
    {
        $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');
        // $join->on('kg_shops.active', '=', "1"); // WRONG
        // EDITED ON 28-04-2014
        $join->on('kg_shops.active', '=', DB::raw("1"));

    });
}

Only problem is, it gives this outcome:

Column not found: 1054 Unknown column '1' in 'on clause' (SQL: select `kg_feeds`.* from `kg_feeds` inner join `kg_shops` on `kg_shops`.`id` = `kg_  
  feeds`.`shop_id` and `kg_shops`.`active` = `1`) (Bindings: array (                                                                                        )) 

As you can see, the multiple conditions in the join go fine, but it thinks the 1 is a column instead of a string. Is this even possible, or do I have to fix it in the where.

0

8 Answers 8

88
return $query->join('kg_shops', function($join)
 {
   $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');

 })
 ->select('required column names') 
 ->where('kg_shops.active', 1)
 ->get();
Sign up to request clarification or add additional context in comments.

1 Comment

You can add the where clause inside the join, so eloquent it will think that "1" is not a column, as Kamlesh says.
73

You can see the following code to solved the problem

return $query->join('kg_shops', function($join)
{
    $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');
    $join->where('kg_shops.active','=', 1);
});

Or another way to solved it

 return $query->join('kg_shops', function($join)
{
    $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');
    $join->on('kg_shops.active','=', DB::raw('1'));
});

3 Comments

If i'm print query log then it is showing AND between both condition. But how I can use or instead of AND
Use it. $join->orOn('kg_shops.active','=', DB::raw('1'));
If the 'active' field contains a string, you have to use DB::raw("'YES'") instead of DB::raw('YES').
37
//You may use this example. Might be help you...

$user = User::select("users.*","items.id as itemId","jobs.id as jobId")
        ->join("items","items.user_id","=","users.id")
        ->join("jobs",function($join){
            $join->on("jobs.user_id","=","users.id")
                ->on("jobs.item_id","=","items.id");
        })
        ->get();
print_r($user);

Comments

23

Because you did it in such a way that it thinks both are join conditions in your code given below:

public function scopeShops($query) {
    return $query->join('kg_shops', function($join)
    {
        $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');
        $join->on('kg_shops.active', '=', "1");
    });
}

So,you should remove the second line:

return $query->join('kg_shops', function($join)
{
    $join->on('kg_shops.id', '=', 'kg_feeds.shop_id');
});

Now, you should add a where clause and it should be like this:

return $query->join('kg_shops', function($join)
{
  $join->on('kg_shops.id', '=', 'kg_feeds.shop_id')->where('kg_shops.active', 1);
})->get();

3 Comments

Hi Sheikh,Thanks for the answer but I tried that. Gives me the following result. PHP Fatal error: Call to undefined method Illuminate\Database\Query\JoinClause::where() in /app/models/Feeds.php on line 35
How can I add more than one join with OR condition? like join On this OR join ON that?
$join->on()->orOn().
12

You can simply add multiple conditions by adding them as where() inside the join closure

->leftJoin('table2 AS b', function($join){
        $join->on('a.field1', '=', 'b.field2')
        ->where('b.field3', '=', true)
        ->where('b.field4', '=', '1');
})

Comments

11

More with where in (list_of_items):

    $linkIds = $user->links()->pluck('id')->toArray();

    $tags = Tag::query()
        ->join('link_tag', function (JoinClause $join) use ($linkIds) {
            $joinClause = $join->on('tags.id', '=', 'link_tag.tag_id');
            $joinClause->on('link_tag.link_id', 'in', $linkIds ?: [-1], 'and', true);
        })
        ->groupBy('link_tag.tag_id')
        ->get();

    return $tags;

Hope it helpful ;)

7 Comments

Instead of using array_map you can do: $linkIds = $links->lists('id', 'id') Also if you have eloquent models using hasMany() with pivot() works well too.
ok very thank for your suggest, I have not found it for a long :(
Sometimes things may not be documented but I tend to look at the source code on Github or the API documentation
:D me too, I will try to reduce unnecessary codes like this, actually I lost time to dig a function like you gave but quited :(
It's just an alias for pluck it doesn't work once you have used get; so in your case $linkIds = $user->links()->pluck('id')
|
6

This is not politically correct but works

   ->leftJoin("players as p","n.item_id", "=", DB::raw("p.id_player and n.type='player'"))

Comments

2

this is it works. You don't have to use $param. I wrote it this way as an example. If you want, you can just write the value in the condition.

public function scopeShops($query){
    $param = 1;
    return $query->join('kg_shops', function ($join) use ($param) {
        $join->on('kg_shops.id', '=', 'kg_feeds.shop_id')
            ->where('kg_shops.active', '=', $param);
    });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.