Join tables in Laravel Eloquent - mysql

I have three tables like this:
user
id | name | department_id
user_verify
id | code | user_id | department_id
department
id | name
I want to query on table user_verify and join with other tables to get username and department name.
I tried this in my model:
class ListUserVerify extends Model
{
protected $table = 'user_verify';
public function getUserVerify()
{
return $this->select("{$this->table}.code",'user.fullname','department.name')
->join('user', 'user.id', '=', "{$this->table}.user_id")
->join('department', 'department.id', '=', "{$this->table}.department_id")
->get();
}
}
But this function return null, I don't know what's wrong with my query.
Can you show me what's wrong I did?
Thank you very much!

Try it.
return \DB::table("{$this->table}")->select("{$this->table}.code",'user.fullname','department.name')
->join('user', 'user.id', '=', "{$this->table}.user_id")
->join('department', 'department.id', '=', "{$this->table}.department_id")
->get();

Try this
return DB::table('user_verify')->leftjoin('user','user.id','=','user_verify.user_id')
->leftjoin('department','department.id','=','user_verify.department_id')
->select('user.name as username','department.name as departmentname')
->get();

Related

Joining same table twice in Laravel

I'm building an application on Laravel where I need to join the same table with some condition
I'm having a project_associate_brand table which includes following columns:
project_id | brand_id | product_group_id | product_sub_group_id
I need to fetch out brands associated with project with respect to product_group_id and product_sub_group_id and also which are the other brands associated with them
To execute this I tried:
AssociatedBrands::where('project_associate_brand.brand_id', '=', $id)
->leftjoin('project_associate_brand as pr_brand', function ($join) {
$join->on('project_associate_brand.project_id', '=', 'pr_brand.project_id')
->where('project_associate_brand.product_group_id', '=', 'pr_brand.product_group_id')
->where('project_associate_brand.product_subgroup_id', '=', 'pr_brand.product_subgroup_id');
})
->leftjoin('brands as b', function ($join) {
$join->on('pr_brand.brand_id', '=', 'b.id')->whereNotIn('pr_brand.brand_id', [$id]);
})
->select('project_associate_brand.*', 'b.id as other_brand_id', 'b.title as other_brand_title')
->paginate(15);
I'm not getting the desired results, I tried removing few of the where clause, when I remove product_group_id and product_sub_group_id contraints I was able to get results
AssociatedBrands::where('project_associate_brand.brand_id', '=', $id)
->leftjoin('project_associate_brand as pr_brand', function ($join) {
$join->on('project_associate_brand.project_id', '=', 'pr_brand.project_id');
//Removed other where clause
})
->leftjoin('brands as b', function ($join) {
$join->on('pr_brand.brand_id', '=', 'b.id')->whereNotIn('pr_brand.brand_id', [$id]);
})
->select('project_associate_brand.*', 'b.id as other_brand_id', 'b.title as other_brand_title')
->paginate(15);
Any better approach is welcome. Further I would like to execute with() eager loading of relations

Display nickname instead of ID number of a table

I have two tables:
users
id nickname
1 Mike
2 John
report
id user_id target_id
1 1 2
2 2 1
MyController
public function violationView(User $user)
{
$vio = Report::all(); //this should be query, but I don't know how.
return view('admin.violation.vio_listpage')
->with('vio', $vio);
}
When I displayed the $vio into my blade, it only displays the user_id and target_id. These should be the nickname of the users and not ID number.
Expected Output
ID user_name(user_id) username(target_id)
1 Mike John
2 John Mike
Does anybody know how to display the nickname instead if user_id and target_id?
To get user name by user id you need to add join with in your query. Below is the example for that:-
$vio = Violation::join('users', function($q) {
$q->on('users.id', '=', 'report.user_id');
})
->join('users as target', function($q) {
$q->on('target.id', '=', 'report.target_id');
})
->selectRaw("report.*, users.nickname as user_name, target.nickname as target_user_name")
->get();
return view('admin.violation.vio_listpage')
->with('vio', $vio);
Try this. I think this will help you to achieve your goal.

Laravel Eloquent equivalent of MYSQL IN

I got two tables. I want to get all users and their details who are active/banned.
What is laravel eloquent equivalent to this query.
'select * from client_details where user_id IN (select user_id from client_logins where is_active='.$active.')'
Table: client_logins Model clientLogin
+---------+---------+--------------+-------------+-----------+
| id | user_id | username | password | is_active |
+---------+---------+--------------+-------------+-----------+
Table: client_details Model clientDetail
+---------+------+-------+------------------+
| user_id | name | email | mobile | address|
+---------+------+-------+------------------+
Using query builder you could write it as
$clients=DB::table('client_details as c')
->select('c.*')
->join('client_logins as l', 'c.user_id', '=', 'l.user_id')
->where('l.is_active', '=', $active)
->get()
;
Or if have defined has relation for ClientDetails model you can use whereHas filter
class ClientDetails extends Model
{
public function client_logins()
{
return $this->hasMany('App\ClientLogins', 'user_id', 'user_id');
}
}
$clients = ClientDetails::whereHas('client_logins', function ($query) use ($active) {
$query->where('is_active', '=', $active);
})->get();

Join and SUM in Laravel ELoquent

Database Structure is as follows:
Table: users
id | name | email | password
Table: analytics
id | user_id(fk) | article_id(fk) | revenue | date | clicks
Now I want the list of all users with the sum of their own revenue from these two Tables.
What I tried is as follows:
$users = User::select('users*', 'analytics.*', 'SUM(analytics.revenue)')
->leftJoin('analytics', 'analytics.user_id', '=', 'users.id)
->where('analytics.date', Carbon::today()->toDateString())
->get();
But it is throwing me error.
You may try this
$users = User::select('users*', 'analytics.*', DB::raw('SUM(analytics.revenue) As revenue'))
->leftJoin('analytics', 'analytics.user_id', '=', 'users.id')
->where('analytics.date', Carbon::today()->toDateString())
->get();
$users = User::select(\DB::raw('users.*, SUM(analytics.revenue) as revenue'))
->leftJoin('analytics', 'analytics.user_id', '=', 'users.id')
->groupBy('users.id')
->get();
This maybe a bit late. Maybe will help someone else.
You need to include every select columns in groupBy. In your case:
$users = User::select('users.id', 'users.name', 'users.password', 'analytics.date', 'analytics.clicks', 'SUM(analytics.revenue) as revenue')
->leftJoin('analytics', 'users.id', '=', 'analytics.user_id')
->where('analytics.date', Carbon::today()->toDateString())
->groupBy('users.id', 'users.name', 'users.password', 'analytics.date', 'analytics.clicks')
->get();

Laravel join with 3 Tables

I am building a Twitter-like app. There is a Feed in which I want to only show posts of Users who I follow.
I tried everything with joins, but nothing seems to work.
I have 3 tables: Users, Followers, Shares
The Tables look like this:
Users: id
Followers: user_id, follower_id
Shares: user_id
What I need to get is "ALL Shares WHERE share.user_id = followers.follower_id"
"ANDWHERE followers.user_id = users.id"
Assume, the users.id is 3, I tried this:
$shares = DB::table('shares')
->leftjoin('followers', 'shares.user_id', '=', 'followers.follower_id')
->leftjoin('users', 'followers.user_id', '=', 'users.id')
->where('users.id', 3)
->where('shares.user_id', 'followers.follower_id')
->get();
But it doesnt work.
Any help is appreciated :)
I believe your join is wrong:
$shares = DB::table('shares')
->join('users', 'users.id', '=', 'shares.user_id')
->join('followers', 'followers.user_id', '=', 'users.id')
->where('followers.follower_id', '=', 3)
->get();
I also suggest you to name your table as follows instead, it feels a bit more natural to say user has many followers through follows and user has many followees through follows.
Example
$shares = DB::table('shares')
->join('users', 'users.id', '=', 'shares.user_id')
->join('follows', 'follows.user_id', '=', 'users.id')
->where('follows.follower_id', '=', 3)
->get();
Model approach
I didn't realize you were using DB:: queries and not models. So I'm fixing the answer and providing a lot more clarity. I suggest you use models, it's a lot easier for those beginning with the framework and specially SQL.
Example of models:
class User extends Model {
public function shares() {
return $this->hasMany('Share');
}
public function followers() {
return $this->belongsToMany('User', 'follows', 'user_id', 'follower_id');
}
public function followees() {
return $this->belongsToMany('User', 'follows', 'follower_id', 'user_id');
}
}
class Share extends Model {
public function user() {
return $this->belongsTo('User');
}
}
Example of Model usage:
$my = User::find('my_id');
// Retrieves all shares by users that I follow
// eager loading the "owner" of the share
$shares = Share::with('user')
->join('follows', 'follows.user_id', '=', 'shares.user_id')
->where('follows.follower_id', '=', $my->id)
->get('shares.*'); // Notice the shares.* here
// prints the username of the person who shared something
foreach ($shares as $share) {
echo $share->user->username;
}
// Retrieves all users I'm following
$my->followees;
// Retrieves all users that follows me
$my->followers;
In terms of general MySQL syntax, this is best written:
SELECT * FROM USER a JOIN FOLLOWERS b ON (a.id = b.user_id) JOIN SHARES c on (b.follower_id = c.user_id) WHERE a.id = 3
will return a data set of all followers and their respective shares.
I believe you would want the following in Laravel
DB::table('USER')
->join('FOLLOWERS', 'USER.id', '=', 'FOLLOWERS.user_id')
->join('SHARES', 'FOLLOWERS.follower_id', '=', 'SHARES.user_id')
->where('USER.id', 3)
->get();
Instead of
->where('shares.user_id', 'followers.follower_id')
It should be
->whereRaw('shares.user_id=followers.follower_id')
because on the original example the 'followers.follower_id' is interpreted as a string.
$data[shares] = DB::table('shares')
->leftjoin('followers', 'shares.user_id', '=', 'followers.follower_id')
->leftjoin('users', 'users.id', '=', 'users.id')
->where('users.id','=', 3)
->get();
to see results.
print_r($data[shares]);die;
for other query Simply give discription of your table
First of all, go through users table and join it with followers table, and then with share table to get corresponding shares data of only followers. Here is the code
$shares = DB::table('users')
->leftjoin('followers', 'users.user_id', '=', 'followers.follower_id')
->leftjoin('shares', 'shares.user_id', '=', 'users.id')
->where('users.id', 3)
->get();