How can i write nested query in laravel - laravel

SELECT * FROM posts WHERE user_id IN (SELECT following FROM follows WHERE user_id='1'
This is the query i want to wirte in laravel to fetch the data how can i write this in laravel

This should work:
$result = DB::table('posts')
->whereIn('user_id', function ($query) {
$query->select('following')
->from('follows')
->where('user_id', 1);
})->get();

Related

Eloquent with query on relations with nested WHERE

I'm struggling with Eloquent with query on relation.
For example, I'm looking for only the client John who doesn't have transaction.
How can I do this with Eloquent?
Client model relation
public function transactions()
{
return $this->hasMany(Transaction::class);
}
$results = Client::whereDoesntHave('transactions', function ($query) use ($inputFirst, $period) {
$query->where('transactions.period_id', '=', $period->id)
->where('firstname', '=', $inputFirst);
})
->orderBy('id', 'desc')
->get();
A little help would be great.
Thanks
The issue with your code is that you are nesting the statements. The way you are doing Laravel is generating a SQL like this:
select * from `clients` where not exists
(select * from `transactions`
where `clients`.`id` = `transactions`.`client_id`
and `name` = John)
But the actual SQL code you're looking for is:
select * from `clients` where not exists
(select * from `transactions`
where `clients`.`id` = `transactions`.`client_id`)
and `name` = John)
For that your code should be:
$results = Client::whereDoesntHave('transactions')
->where('firstname', '=', $inputFirst)
->orderBy('id', 'desc')
->get();
*I didn't include the transactions.period_id, coz I wasn't sure if where you're looking to have it. But if it's meant to be inside the second select, leave in the nested statement, if not leave outside.

Trouble converting an SQL query to Eloquent

Trying to get this query to work in eloquent
A user can be in multiple teams however I want to generate a list of users NOT in a specific team. The following SQL query works if executed directly but would like to make it cleaner by converting it to eloquent
SELECT * FROM users LEFT JOIN team_members ON team_members.member_id = users.id WHERE NOT EXISTS ( SELECT * FROM team_members WHERE team_members.member_id = users.id AND team_members.team_id = $team_id )
This should provide a list of all the users that are not members of team $team_id
This is a guess ad you do not give much info on your Eloqent models but here is a hint of where to go:
User::doesnthave('teamMembers', function($builder) use($team_id){
return $builder->where('team_members.team_id');
});
That is assuming you have a "User" model with a "teamMembers" relationship setup on it
You may have a closer look in the Laravel docs for doesntHave
Laravel 5.8
Let's assume you have model name "User.php"
& there is method name "teamMembers" in it.
Basic
$users = User::doesntHave('teamMembers')->get();
Advance
use Illuminate\Database\Eloquent\Builder;
$users = User::whereDoesntHave('teamMembers', function (Builder $query) {
$query->where('id', '=', {your_value});
})->get();
You can find details description in this link >>
https://laravel.com/docs/5.8/eloquent-relationships#querying-relationship-absence
Laravel 5.2
Example:
DB::table('users')
->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('orders')
->whereRaw('orders.user_id = users.id');
})
->get();
Check this link for advance where clause:
https://laravel.com/docs/5.2/queries#advanced-where-clauses
You can use below example
$list = User::leftJoin('users', 'users.id', '=', 'team_members.member_id')
->whereNotExists(function ($query) use ($team_id) {
$query->from('team_members')
->whereRaw('team_members.member_id = users.id')
->where('team_members.team_id', '=', $team_id);
})
->get();

Laravel nested whereIn from multiple tables

I'm using Laravel 5.7. How do i rewrite below code as a single nested query?
I'm currently fetching the result using 2 database queries. I go through some of the answers in stackoverflow, but i still have doubts in nesting multiple tables
$connectedParts = DB::table('part_connections as c')
->join('parts_master as p', 'p.id', '=', 'c.part_number_id')
->where('c.part_number_id', $partId)
->where('p.id', $partId)
->pluck('connected_to');
$connectedComponents = DB::table('part_connections as pc')
->join('parts_master as pm', 'pm.id', '=', 'pc.connected_to')
->where('part_number_id',$partId)
->where('pm.part_type','1')
->whereIn('connected_to', $connectedParts)
->pluck('connected_to');
Any help would be greatly appreciated.
Set your relationship properly in your model first then try this query:
//PartConnection model - add for eager loading
public function master() {
return $this->belongsTo('PartMaster::class', 'connected_to', 'id');
}
$query = PartConnection::whereHas(‘master’, function($qry)) use ($partId) {
$qry->where(‘parts_master.id’, $partId);
$qry->where(‘parts_master.part_type’, 1);
});
$query->where(‘part_number_id’, $partId);
$connectedComponents = $query->get();
update
Try this then:
$connectedComponents = DB::table('part_connections as pc')
->join('parts_master as pm', function($join) {
$join->on('pc.connected_to', '=', 'pm.id');
$join->on('pc.part_number_id', '=', 'pm.id');
}) //updated this - removed ;
->where('part_number_id',$partId)
->where('pm.part_type','1')
->get();

Laravel select * where id =(select id )

Using Laravel eloquent how do I make a query like this:
select * from branches where user_id =(select id from users where name ='sara' )
Assuming that you have a user relationship in your Branch model you could use whereHas:
$branches = Branch::whereHas('user', function ($query) {
$query->where('name', 'sara');
})->get();
Update
If you're using v8.57.0 or above, you can now use the whereRelation() method instead:
Branch::whereRelation('user', 'name', 'sara')->get();
$id = Users::select('id')->where('name','sara')->first();
$barnches = branches::where('id',$id)->get();
Here Users and branches are models , first is using for 1 row and get for many rows
I would split it into two queries. First getting the id, then getting the list. Expecting your models to be called "User" and "Branches"
$user = User::where('name', 'sara');
$id = $user->id;
$branches = Branch::where('id', $id);
This site may help you Link
Try this.
$name = 'sara';
$results = BranchModel::whereIn("user_id", function ($query) use ($name) {
$query->select("id")
->from((new UserModel)->getTable())
->where("name", $name);
})->get();
You can use this:
$users = User::whereName("sara")->get()->pluck('id');
Branch::whereIn('user_id',$users)->get();

Why query returns empty collection?

I have the following query was built by Laravel:
$res = Announcement::whereExists(function ($query) {
$query->select(DB::raw(1))
->from('announcement_category')->join('user_category', 'user_category.category_id', '=', 'announcement_category.category_id')
->where('user_category.user_id', '=', 1)
->where('announcement_category.announcement_id', '=', 'announcements.id');
});
dd($res->get());
The code above gives me empty collection: dd($res->get());.
The plain SQL code of this query is:
select * from `announcements` where exists (select 1 from
`announcement_category` inner join `user_category` on
`user_category`.`category_id` = `announcement_category`.`category_id` where `user_category`.`user_id` = 1
and `announcement_category`.`announcement_id` = announcements.id)
and `announcements`.`deleted_at` is null
If execute this directly in MySQL, I get two result rows.
But why dd($res->get()); retuns me empty?
I don't think there is a whereExists in eloquent model... try this:
$res = DB::table('announcement')->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('announcement_category')->join('user_category', 'user_category.category_id', '=', 'announcement_category.category_id')
->where('user_category.user_id', '=', 1)
->where('announcement_category.announcement_id', '=', 'announcements.id');
})->get();

Resources