I have a collection of user skills but i need is to get only skills as an array i tried this
$builder->where('job_id', $value)
->join('users', 'job_applicants.user_id', '=', 'users.id')
->join('user_skills', 'users.id', '=', 'user_skills.user_id', function ($join){
$join->selectRaw("GROUP_CONCAT(user_skills.skill, ', ')");
})
->groupBy('job_applicants.job_id')
->get();
The exception message : Object of class Closure could not be converted to string
The join closure should be the first and only argument after the table name.
->join('user_skills', function ($join) {
$join->on('users.id', '=', 'user_skills.user_id')
->selectRaw("GROUP_CONCAT(user_skills.skill, ', ')");
});
However, a selectRaw inside the join closure doesn't make a whole lot of sense. Logically, this isn't where you select data. You've joined the table, your select statement belongs in the main query, it doesn't belong contained within the join, like so:
$builder->selectRaw("job_applicants.*, GROUP_CONCAT(user_skills.skill, ', ')")
->where('job_id', $value)
->join('users', 'job_applicants.user_id', '=', 'users.id')
->join('user_skills', 'users.id', '=', 'user_skills.user_id')
->groupBy('job_applicants.job_id')
->get();
Related
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
Good day all, I am trying to count all records in a table but only if the table does not contain data in a specific column (deleted_at). It is a join table the table names are companies and employees. I am currently counting the records with a DB::raw but it should only count it if the deleted_at column is null. Please understand that i am a beginner.
public function index()
{
$user = Auth::user()->id;
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('COUNT(e.id) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->where('c.deleted_at', '=', null)
->groupBy('c.id')
->get();
return view('account.companies.index')
->with('companies', $companies);
}
If you are using Mysql then you could use conditional aggregation
$companies = DB::table('companies AS c')
->select([
'c.id',
'c.logo',
'c.company_name',
'c.created_at',
'c.sector',
'c.deleted_at',
DB::raw('SUM(c.deleted_at IS NULL) AS employee_count')
])
->leftJoin('employees AS e', 'e.company_id', '=', 'c.id' )
->leftJoin('company_user AS cu', 'cu.company_id', '=', 'c.id')
->where('cu.user_id', '=', $user)
->groupBy('c.id')
->get();
In mysql when an expression is used inside sum(a= b) it will result as a boolean 0/1 so you can get your conditional count using above
Or you could use whereNull() method in your query
->whereNull('c.deleted_at')
Use this code:
$employeeCount = DB::table('employees')
->select('companies.name', DB::raw('count(employees.id) as employee_count'))
->join('companies', 'employees.company','=','companies.id')
->groupBy('companies.id')
->get();
I try these code in MySQl:
SELECT
A.*,
B.name,
C.name
FROM
eventlog_tbl as A
LEFT JOIN users B ON A.byuser=B.email
LEFT JOIN users C ON A.affectiveuser=C.email;
I try these in Laravel
return DB::table('eventlog_tbl')
->leftjoin('users', 'users.email', '=', 'eventlog_tbl.byuser')
->leftjoin('users', 'users.email', '=', 'eventlog_tbl.affectiveuser')
->select('eventlog_tbl.*','users.name','users.name')
->get();
How can i convert it to Laravel?
Try below code:
$res = DB::table('eventlog_tbl')
->leftjoin('users AS A', 'A.email', '=', 'eventlog_tbl.byuser')
->leftjoin('users AS B', 'B.email', '=', 'eventlog_tbl.affectiveuser')
->select('eventlog_tbl.*','A.name as byuser_name','B.name as affectiveuser_name')
->get();
print_r($res);
This is your query written using the Laravel query builder.
$events = DB::table('eventlog_tbl')
->select('eventlog_tbl.*', 'users_1.name', 'users_2.name')
->leftJoin('users AS users_1', 'users_1.email', '=', 'eventlog_tbl.byuser')
->leftJoin('users AS users_2', 'users_2.email', '=', 'eventlog_tbl.affectiveuser')
->get();
Edit:
$events = DB::table('eventlog_tbl')
->select('eventlog_tbl.*', 'users_1.name AS user_1', 'users_2.name AS user_2')
->leftJoin('users AS users_1', 'users_1.email', '=', 'eventlog_tbl.byuser')
->leftJoin('users AS users_2', 'users_2.email', '=', 'eventlog_tbl.affectiveuser')
->get();
The problem is that both name columns are called the same thing. As per the accepted answer, these will need to be aliased differently too.
Why don't you convert this to use relationships? I have probably got the relationships wrong, something like this:
class EventLog extends Model
{
public function byUser()
{
return $this->hasOne(User::class, 'byuser', 'id');
}
public function affectiveUser()
{
return $this->hasOne(User::class, 'affectiveuser', 'id');
}
}
And then
$event_log = EventLog::with(['byUser', 'affectiveUser')->all();
foreach ($event_log as $item) {
echo $item->byUser->email();
}
What i'm trying to achieve is the following:
I want to check if there is a record with the same client_code but with a lower/different campaign id. I'm using a sub-query for now and i tried to do it with a join as well but I couldn't get the logic working
This is what i got now:
$oDB = DB::table('campaigns AS c')
->select(
'c.id AS campaign_id',
'cc.id AS campaign_customer_id'
)
->join('campaign_customers AS cc', 'cc.campaign_id', '=', 'c.id')
->where('c.status', '=', ModelCampaign::STATUS_PLANNED)
->where('c.scheduled', '=', 1)
->whereRaw('c.scheduled_at <= NOW()')
->where('cc.status', '=', ModelCampaignCustomer::STATUS_INVITE_EMAIL_SCHEDULED)
->whereNotIn('cc.client_code', '=', function ($query){
$query ->select(DB::raw(1))
->from('campaign_customers')
->whereRaw('campaign_id', '!=', 'c.id');
})
->where('cc.active', '=', 1)
;
any tips on how to work the logic would be great
You can use the ->toSql(); method to see the SQL so you can refactorize your query.
The whereNotIn probably shouldn't have an = in it
->whereNotIn('cc.client_code', function ($query){
....
edit
Try:
->whereNotIn('cc.client_code', function ($query){
$query->select(DB::raw('client_code'))
->from('campaign_customers')
->whereRaw('campaign_id != c.id');
})
I think the whereRaw should be a single text string or maybe you can use where here (looking at this for reference https://laravel.com/docs/5.2/queries#advanced-where-clauses). Also DB::raw(1) is going to return a 1 for each subquery result but you want an id for the whereNotIn.
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();