77

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.

starball
  • 20,030
  • 7
  • 43
  • 238
Wouter Neuteboom
  • 796
  • 1
  • 8
  • 22

8 Answers8

86
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();
rama
  • 892
  • 6
  • 2
68

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'));
});
Majbah Habib
  • 8,058
  • 3
  • 36
  • 38
32
//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);
Yagnesh bhalala
  • 1,107
  • 1
  • 15
  • 17
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();
The Alpha
  • 143,660
  • 29
  • 287
  • 307
11

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');
})
Kamlesh
  • 5,233
  • 39
  • 50
10

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 ;)

ThangTD
  • 1,586
  • 17
  • 16
  • 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. – Ash Apr 25 '16 at 08:23
  • ok very thank for your suggest, I have not found it for a long :( – ThangTD Apr 25 '16 at 08:25
  • Sometimes things may not be documented but I tend to look at the source code on [Github](https://github.com/laravel/framework/tree/5.2/src/Illuminate) or the [API documentation](https://laravel.com/api/5.2/) – Ash Apr 25 '16 at 08:29
  • :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 :( – ThangTD Apr 25 '16 at 08:33
  • Hey @ash, the `->lists()` is deprecated on 5.2. Use `->pluck()` instead, but actually I gave tries with pluck for nothing as my expected result. – ThangTD Apr 25 '16 at 08:35
  • 1
    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')` – Ash Apr 25 '16 at 08:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110127/discussion-between-thangtd-and-ash). – ThangTD Apr 25 '16 at 10:09
6

This is not politically correct but works

   ->leftJoin("players as p","n.item_id", "=", DB::raw("p.id_player and n.type='player'"))
Uncoke
  • 1,832
  • 4
  • 26
  • 58
0

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);
    });
}
pirix
  • 1
  • 1