0

I have four tables: users, orders, shares, and horses.

One user has many orders, one order has many shares, and one horse has many shares.

I want to find how many shares of each horse does a specific user owns (including when a user owns zero shares in a particular horse).

I have tried the following, however I cannot retrieve the cases when a user owns zero shares for a particular horse.

$userHorses = DB::table('orders')->join('shares', 'orders.id', '=', 'shares.order_id')
          ->join('horses', 'horses.id', '=', 'shares.horse_id')
          ->where('orders.user_id',$user_id)
          ->select('horses.name','horses.id','horses.slug',DB::raw('count(*) as totalShares'))
          ->groupBy('horses.name','horses.id','horses.slug')
          ->get();

return $userHorses;
Petro Bianka
  • 135
  • 1
  • 8
  • Here is your problem visualized: https://stackoverflow.com/questions/5706437/whats-the-difference-between-inner-join-left-join-right-join-and-full-join – online Thomas Aug 18 '20 at 14:35

1 Answers1

0

To retrieve all horses with user share count you will need left join with conditional aggregation like

$userHorses = DB::table('horses h')
          ->leftJoin('shares s', 'h.id', '=', 's.horse_id')
          ->leftJoin('orders o', 'o.id', '=', 's.order_id')
          ->select('h.name',
            'h.id',
            'h.slug',
            DB::raw('sum(case when o.user_id = :user_id then 1 else 0 end) as totalShares', ['user_id' => $user_id])
          )
          ->groupBy('h.name','h.id','h.slug')
          ->get();
M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118