Eloquent join table with two conditions - php

I have two tables:
A: id | user_id | phonenumber | status | ...
B: id | user_id | phonenumber | name | ...
I would like to list all elements in table A but I have to left join the elements to table B.
I can do it with DB:
DB::table('A')
->leftJoin('B', function ($join) {
$join->on('A.phonenumber', '=', 'B.phonenumber')
->on('A.user_id', '=', 'B.user_id');
})
->select(...)
->where('A.user_id', '=', $userId)
->get();
Is it possible to solve it with eloquent somehow?

You can use eloquent, one way is to change it to
A::leftJoin('B', function ($join) {
$join->on('A.phonenumber', '=', 'B.phonenumber')
->on('A.user_id', '=', 'B.user_id');
})
->select(...)
->where('A.user_id', '=', $userId)
->get();
And with using pure eloquent
You would have to do adjustment to your A model. We would define two model functions.
public function phoneNumber()
{
return $this->hasMany(B::class, "phonenumber", "phonenumber");
}
public function userId()
{
return $this->hasMany(B::class, "user_id", "user_id");
}
Now we will change our query to
A::with("phonenumber")->has("phonenumber")
->with("userId")->has("userId")
->where("user_id","=",$userId)
->get();
This should work for you.
** Updated ***
if you want all the record in A then simply do
A::with("phonenumber","userId")
->where("user_id","=",$userId)
->get();

modelname::where(condition)->leftjoin(tablename,fieldname,othertable.fieldname)->get()
This is format how we write join in laravel
$postdata = post::select('categories.id', 'posts.id', 'categories.categoryname', 'posts.title', 'posts.body', 'posts.image', 'posts.created_at', 'users.name')
->where('post_type', 'publish')
->where('status', 'active')
->where('categories.id', $id)
->leftJoin('users', 'users.id', '=', 'posts.user_id')
->leftJoin('categories', 'categories.id', '=', 'posts.category')
->orderBy('created_at', 'desc')
->paginate(5);
This query display blog with username and with category using join it's my proect convenient query you can also create for you in this manner

Related

How can i join the results only with specific rows in another table on Laravel?

I have these tables:
user_points
- user_class_id
- scoreable_id
-scoreable_type
points_interaction_system
- user_id
- points
- type
supplementary_assessments
- user_id
- points
In user_points table the scoreable_type will receive the model of the one of the other tables like App\Models\SupplementaryAssessment or App\Models\PointInteractionSystem and the scoreable_id the id of the model.
What i want to do is join the supplementary table records only with the rows in the user_points that have in the scoreable_type the model SupplementaryAssessment and join the points_interaction_system records only the rows in the user_points that have in the scoreable_type the model PointInteractionSystem. At the end i want sum all the points fields based on the user id.
I did something like this, but its not working:
DB::table('user_points')
->join('user_classes', function ($join) use ($user) {
$join->on('user_points.user_class_id', '=', 'user_classes.id')
->where('user_classes.user_id', $user->id);
})
->leftJoin('supplementary_assessments', function ($join) {
$join->on('user_points.scoreable_id', '=', 'supplementary_assessments.id')
->where('user_points.scoreable_type', 'like', '%SupplementaryAssessment');
})
->leftJoin('points_interaction_system', function ($join) {
$join->on('user_points.scoreable_id', '=', 'points_interaction_system.id')
->where('user_points.scoreable_type', 'like', '%PointInteractionSystem');
})
->get();
Try something like:
DB::table('user_points')
->join('user_classes', function ($join) use ($user) {
$join->on('user_points.user_class_id', '=', 'user_classes.id')
->where('user_classes.user_id', $user->id);
})
->join('supplementary_assessments', function ($join) {
$join->on('user_points.scoreable_id', '=', 'supplementary_assessments.id')
->where('user_points.scoreable_type', 'like', '%SupplementaryAssessment%');
})
->join('points_interaction_system', function ($join) {
$join->on('user_points.scoreable_id', '=', 'points_interaction_system.id')
->where('user_points.scoreable_type', 'like', '%PointInteractionSystem%');
})
->get();
Uses join instead of left-join.

How can I separate out the Ids in tables joined within a Laravel Project

I have the following that joins together 3 tables, Images, Users, Profiles. The problem I have is that the result of the following only gives me 1 id field and that is the Id of the Profiles table. All 3 tables have their own Id fields.
Can I seperate it so that it is images.id, profiles.id and users.id?
$images = \App\Image::where('image_approved', '=' ,"feature_approved")
->join('users', 'users.id', '=', 'images.user_id')
->join('profiles', 'profiles.user_id', '=', 'images.user_id')
->get();
You can alias them like this:
$images = \App\Image::select([
'users.id as user_id',
'profiles.id as profile_id',
'images.id as image_id',
//... add the rest of the columns that you want to select here.
])
->where('image_approved', '=' ,"feature_approved")
->join('users', 'users.id', '=', 'images.user_id')
->join('profiles', 'profiles.user_id', '=', 'images.user_id')
->get();
or you can simplify it by using Eloquent relationships.
So in your Image model you would have:
public function user()
{
return $this->belongsTo(User::class);
}
public function profile()
{
return $this->hasOneThrough(Profile::class, User::class);
}
Then you can retrieve them:
$images = Image::with('user', 'profile')
->where('image_approved', '=' ,"feature_approved")
->get();
// now each $image in $images will have user and profile relationship
// $image->id
// $image->user->id
// $image->profile->id
Use alias in select like this:
->join('profiles', 'profiles.user_id', '=', 'images.user_id')
->select('images.*', 'users.*', 'profiles.*', 'images.id as imageID', 'profiles.id as profileId', 'users.id as usersId')
->get();

Laravel query relationship where clause

I need filter by departamento, like where('departamento_id', '=', 1).
Tables:
membro_bancas
id
departamento_id
user_id
trabalhos
id
titulo
orientador_id (references id of membro_bancas)
coorientador_id (references id of membro_bancas)
I have this code:
$trabalho = Trabalho::with('membrobanca.departamento')
->with('coorientador')
->with('academico')
->get();
And returns this:
I got it!
I needed add orWhereHas for coorientador too. The result is this:
Trabalho::whereHas('membrobanca', function($q) use ($departamento_id) {
$q->where('departamento_id', '=', $departamento_id);
})
->orWhereHas('coorientador', function($q) use ($departamento_id) {
$q->where('departamento_id', '=', $departamento_id);
})
->with('academico')
->get();
Try this eloquent filter using whereas
$trabalho = Trabalho::whereHas('membrobanca',function($query) use ($id){
$query->where('departamento_id', '=', $id)
})
->with('coorientador')
->with('academico')
->get();
example of filter using with
$trabalho = Trabalho::with(['membrobanca',function($query) use ($id){
$query->where('departamento_id', '=', $id)
}])
->with('coorientador')
->with('academico')
->get();

Laravel Eloquent Complex Join Statement - specific example provided

I have the following raw SQL that I'm trying to convert into Eloquent form:
SELECT oe.eventID, oe.eventName, oet.etName, date_format(oe.eventStartDate, '%c/%d/%Y') as eventStartDate,
date_format(oe.eventEndDate, '%c/%d/%Y') AS eventEndDate
FROM `org-event` oe
JOIN `org-event_types` oet on oe.eventTypeID=oet.etID and oet.orgID=?
JOIN `event-registration` er on er.eventID = oe.eventID
WHERE (er.regStatus='Active' or er.regStatus='In Progress') AND personID=? AND oe.deleted_at is NULL
ORDER BY oe.eventStartDate DESC
I've crafted the following and I'm running into an error saying that '10' isn't a column. 10 is the value of $this->currentPerson->defaultOrgID
DB::table('org-event')
->join('org-event_types', function($join) {
$join->on('org-event_types.etID', '=', 'org-event.eventTypeID');
$join->on('org-event_types.orgID', '=', $this->currentPerson->defaultOrgID);
})->join('event-registration', 'event-registration.eventID', '=', 'org-event.eventID')
->where('event-registration.personID', '=', auth()->user()->id)
->where(function($w) {
$w->where('event-registration.regStatus', '=', 'Active')
->orWhere('event-registration.regStatus', '=', 'In Progress');
})
->select('org-event.eventID', 'eventName', 'etName', 'eventStartDate', 'eventEndDate')
->orderBy('org-event.eventStartDate')->get();
I dropped the deleted_at where clause because that's automatic using eloquent.
You have to join on the corresponding foreign key: oe.eventTypeID=oet.etID and then supply a where explaining what you want to filter your results by, i.e. ->where('orgID','=',$this->currentPerson->defaultOrgID).
DB::table('org-event')
->join('org-event_types', function($join) {
$join->on('org-event_types.etID', '=', 'org-event.eventTypeID');
$join->on('org-event_types.orgID', '=', 'org-event.eventTypeID')->where('orgID','=',$this->currentPerson->defaultOrgID);
})->join('event-registration', 'event-registration.eventID', '=', 'org-event.eventID')
->where('event-registration.personID', '=', auth()->user()->id)
->where(function($w) {
$w->where('event-registration.regStatus', '=', 'Active')
->orWhere('event-registration.regStatus', '=', 'In Progress');
})
->select('org-event.eventID', 'eventName', 'etName', 'eventStartDate', 'eventEndDate')
->orderBy('org-event.eventStartDate')->get();

Laravel Eloquent query get users from another model

I have another table called tableb and it has a user relationship defined through the user_id field.
I want to run a query against tableb where a certain date is within a certain range but then I want to grab the user table associated with that row but I only want it to grab the user if it's not been grabbed yet. I'm trying to do this all in 1 DB query. I have most of it done, but I'm having trouble with the unique part of it.
Here's what I have right now:
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->get();
So right now I have 3 entries in tableB from the same user, and ideally I'd like to only get 1 entry for that user.
How would I go about doing this?
Since you're selecting only users data, just add a groupBy clause in your query.
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get();
You should just add groupBy like this :
$tableB = TableB::select('users.*')
->join('users', 'tableb.user_id', '=', 'users.id')
->where('tableb.start_date', '>', date('Y-m-d'))
->groupBy('users.id')
->get
Try This Code
App/user.php
public function getrelation(){
return $this->hasMany('App\tableB', 'user_id');
}
In Your Controller
Controller.php
use App/user;
public funtion filterByDate(user $user)
{
$date = '2016-02-01';
$result = $user->WhereHas('getrelation', function ($query) use($date) {
$query->whereDate('tableb.start_date', '>', $date)
->first();
});
}

Categories