Sid
Sid

Reputation: 5833

advance join in laravel 5

I have a user table like this

+----+------------+-----------+---------+
| id | first_name | last_name | address |
+----+------------+-----------+---------+
| 1  |     x      |     y     |    z    |
| 2  |     a      |     b     |    c    |
| 3  |     p      |     q     |    r    |
+----+------------+-----------+---------+

and a transfer table like this

+----+--------------+------------+--------+
| id | from_user_id | to_user_id | amount |
+----+--------------+------------+--------+
| 1  |      1       |     2      |   20   |
| 2  |      2       |     1      |   10   |
| 3  |      3       |     2      |   10   |
+----+--------------+------------+--------+

Now I can use join query like this

 $transfer = DB::table('users')
            ->join('transfers', function($join) {
                $join->on('users.id', '=', 'transfers.from_user_id');
            })
            ->select('users.first_name','users.last_name', 'transfers.amount', 'transfers.date')
            ->get();

but doing this will ony give me the first_name and last_name corresponding to from_user_id . But i also want the corresponding first_name and last_name respective to to_user_id. How can I get them?

my desired output table

+---------+---------+--------+
| sent_by | sent_to | amount |
+---------+---------+--------+
|   xy    |   ab    |   20   |
|   ab    |   xy    |   10   |
|   pq    |   ab    |   10   |
+---------+---------+--------+

Here is the MySQL query needed to generate the above table. As you can see, it requires 2 inner joins:

SELECT CONCAT(u1.first_name, u1.last_name), CONCAT(u2.first_name, u2.last_name), t.amount
FROM transfer t INNER JOIN user u1
ON t.from_user_id = u1.id
INNER JOIN user u2
ON t.to_user_id = u2.id

Upvotes: 2

Views: 3107

Answers (2)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 520918

Here is my attempt at a solution for your Laravel query:

$transfer = DB::table('transfer')
                     ->join('user as u1', 'transfer.from_user_id', '=', 'u1.id')
                     ->join('user as u2', 'transfer.to_user_id', '=', 'u2.id')
                     ->select(DB::raw('CONCAT(u1.first_name, u1.last_name) AS sent_by'), 
                              DB::raw('CONCAT(u2.first_name, u2.last_name) AS sent_to'),
                              'transfer.amount as amount')
                     ->get();

The trick is knowing how to include an alias for the double join from transfer to the user table, as well as using DB::raw() to access the MySQL CONCAT function.

Upvotes: 2

CDF
CDF

Reputation: 194

use aliases on your join tables. Hope that helps.

$transfer = DB::table('transfers')
    ->join('users as senders', function($join) {
        $join->on('transfers.from_user_id', '=', 'senders.id');
    })
    ->join('users as receivers', function($join) {
        $join->on('transfers.to_user_id', '=', 'receivers.id');
    })
    ->select('senders.first_name','senders.last_name', 'receivers.first_name','receivers.last_name', 'transfers.amount', 'transfers.date')
    ->get();

Upvotes: 2

Related Questions