sum of columns in another table - laravel - laravel

There's a loan table and loan_addition table. How can I sum the added_amt of loan_addition table and show them while returning loan table data?
loan_addition table
id loan_id added_amt
1 1 100
2 1 200
controller
$data = Loan::select('*')
->with('loanAddition') // how to sum all the columns of respective loan_id here
->get();
dd($data);
loan model
class Loan extends Model
{
public function loanAddition() {
return $this->hasMany(LoanAddition::class);
}
}
LoanAddition model
class LoanAddition extends Model
{
public function loan()
{ return $this->belongsTo(Loan::class); }
}
Thanks in advance..

You can use withSum() method as stated here
$records = Loan::select('*')->withSum('loanAddition', 'loan_id')->get();
Then get the data like below:
$records->pluck('loanAdditions_sum_loan_ids');
Update: for laravel below 8.12
Loan::select('*')->withCount(['loanAddition as loan_id'=>function($query){
$query->select(DB::raw("SUM(loan_id) as loan_id"));
}])->get()

$data = Loan::select('*')
->with(['loanAddition',function($query){
$query->select('sum(added_amt) as sum_added_amt')
}]) // how to sum all the columns of respective loan_id here
->get();
dd($data);
or you can do is $data->first()->sum('loanAddition.added_amt) where you want sum

Related

How to retrieve data from two table in Laravel Eloquent

I have two DB tables.
education_institutions
id institution_name country city logo description
1 ABC College UK London null null
user_educations
id user_id institution_id grade year
1 1 1 3.2 2010
Relationships with both models are
UserEducation
public function educationInstitution()
{
return $this->hasMany(EducationInstitution::class,'institution_id');
}
EducationInstitution
public function userEducation()
{
return $this->belongsTo(UserEducation::class,'institution_id');
}
Now how can I retrieve all education institutions of a particular user with the institution details from educations_institution table.
I tried something like
public function getUserEducation()
{
$userEducation = auth()->user()->userEducation()
->orderBy('created_at', 'desc')
->get();
return response()->json([
'userEducation' => $userEducation
]);
}
But it retrieves only education institution id like:
I need user educations with corresponding institution details.
You can use with() function for relationship selection.
public function getUserEducation()
{
$userEducation = UserEducation::with('educationInstitution')->where('user_id',auth()->user()->id)
->orderBy('created_at', 'desc')
->get();
return response()->json([
'userEducation' => $userEducation
]);
}

Laravel Eloquent query on pivot table

I have the following tables in my database:
trips
start - date
end - date
type - string
users
name - string
age - integer
trip_users (pivot table for many to many relationship)
trip_id - integer
user_id - integer
I want to get users with age between x-y having trips between dateA and dateB using Eloquent.
Try adding a scope or two to your model.
// User.php
protected $with = ['trips'];
public function trips() {
return $this->belongstoMany(Trip::class);
}
// scope for age
public function scopeAgeBetween($query, $age1, $age2) {
return $query->whereBetween('age', [$age1, $age2]);
}
// scope for trip dates
public function scopeTripDatesBetween($query, $dateStart, $dateEnd) {
return $query->whereDate('trips.start', '>=', $dateStart)
->whereDate('trips.end', '<=', $dateEnd);
}
Then in your code:
User::with('trips')->ageBetween(20, 30)->tripDatesBetween('2020-01-01', '2020-02-01')->get();
I think you are looking for something like this:
User::query()
->whereBetween('age', [$x, $y])
->whereHas('trips', function ($q) {
$q->where('start', '>', $dateA)
->where('end', '<', $dateB)
})
->get();

Laravel: How to get data from 3 tables with relationship

I have 3 Tables:
Customers
id
name
Sales
customer_id
sale_date
Contacts
customer_id
contact_date
There aren't any update operations in the contacts table. Each process opens a new record in the contacts table. So, a user can have more than one records in the contacts table.
Here are my relations in models:
Customer
public function contacts()
{
return $this->hasMany(Contact::class);
}
public function sales()
{
return $this->hasMany(Sale::class);
}
Contact
public function customer()
{
return $this->belongsTo('App\Customer', 'customer_id');
}
Sale
public function customer()
{
return $this->belongsTo('App\Customer');
}
I would like to have the latest record of the contacts table and make it join with the other related tables.
Here is the query which I have tried:
$record = Contact::groupBy('customer_id')
->select(DB::raw('max(id)'));
$result = Customer::query();
$result->where('is_active', 'YES');
$result->with('sales');
$result->whereHas('contacts', function ($q) use($record){
return $q->whereIn('id', $record)->where('result', 'UNCALLED');
});
return $result->get();
In the blade file, I get some result in foreach loops. However, I am unable to get the related data from the sales and contacts table.
#foreach($result as $item)
#foreach($item->sales as $sale) // Has no output and gives error: Invalid argument supplied for foreach()
#foreach($item->contacts as $contact) // Has no output and gives error: Invalid argument supplied for foreach()
Can anyone help me how to display the sale and contact date? Or any idea for how to improve this code quality?
If you want the latest record of the contacts you can declare another relationship on the Customer model, e.g.:
public function latest_contact()
{
return $this->hasOne(Contact::class)->latest('contact_date');
}
BTW you can always declare one or more hasOne additional relationship if you have a hasMany in place the foreign key used is the same.
In this way you can retrieve latest_contact eager loaded with your Customer model:
$customer = Customer::with('latest_contact')->find($id);
Or use this relationship in your queries, something like that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->whereHas('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
Or that:
$customers = Customer::where('is_active', 'YES')
->with('sales')
->with('contacts')
->with('last_contact', function ($q){
return $q->where('result', 'UNCALLED');
})->get();
If you want you can declare last_contact with the additional where:
public function latest_contact()
{
return $this->hasOne(Contact::class)
->where('result', 'UNCALLED')
->latest('contact_date');
}
This way all other queries should be easier.
I hope this can help you.
I'm not sure, but can you try to do the following:
return Customer::where('is_active', 'YES')
->with([
'sale',
'contact' => function ($query) use($record) {
return $query->whereIn('id', $record)->where('result', 'UNCALLED');
}
])->get();

Laravel 5.5: How to get top selling items of a given shop?

My tables are like:
shops
[id]
inventories
[id, shop_id]
orders
[id, shop_id]
order_item
[order_id, inventory_id, quantity]
Models:
//Shop
class Shop extends Model
{
public function inventories()
{
return $this->hasMany(Inventory::class);
}
public function orders()
{
return $this->hasMany(Order::class);
}
}
//Inventory
class Inventory extends Model
{
public function shop()
{
return $this->belongsTo(Shop::class);
}
public function orders()
{
return $this->belongsToMany(Order::class, 'order_items')
->withPivot('quantity');
}
}
//Order
class Order extends Model
{
public function shop()
{
return $this->belongsTo(Shop::class);
}
public function inventories()
{
return $this->belongsToMany(Inventory::class, 'order_items')
->withPivot('quantity');
}
}
Now I want 5 top selling inventories of a given shop, What will be the best possible way to do that?
I'm on Laravel 5.5
select s.id,sum(oi.quantity) as total from munna.shops as s
join munna.inventories as iv on s.id=iv.shop_id
join munna.orders as o on iv.shop_id=o.shop_id
join munna.order_items as oi on o.id=oi.order_id
group by s.id
order by total desc limit 5
First, by looking at your tables on order_item, the order_id and inventory_id will bellong to the same shop for sure? I guess yes because if not you would have 2 different shops with same top order. I dont know why you are doing it like this but it's a bit confusing can't figure out why but I would try this:
public function topOrders()
{
$items = DB::table('shops')
->join('orders', 'shops.id', '=', 'orders.shop_id')
->join('inventories', 'shops.id', '=', 'inventories.shop_id')
->join('order_items', 'orders.id', '=', 'order_items.order_id')
->orderBy('quantity', 'desc')
->take(5)
->get();
return $items;
}
What I wrote should select everything from all 3 rows, if you want to select only the items or whatever you want to select you can specify it adding a select clause
Though this was my own question I found the solution on my own and I want to share the solution with the community. I wanted to solve it using Eloquent because I need the model on the view and didn't want to query the model again.
Inventory::where('shop_id', \Auth::user()->shop_id)
->select(
'inventories.*',
\DB::raw('SUM(order_items.quantity) as quantity')
)
->join('order_items', 'inventories.id', 'order_items.inventory_id')
->groupBy('inventory_id')
->get();
I hope this'll help someone with similar issue. Thanks

How to query from eloquent?

ERD :
enter image description here
Model
Student : id
Course : id
Student_Course (payment) : id, student_id, course_id
The relation between Student and Course is Many to Many, because of that I make another table Student_Course.
I have one question, that is Show total amount of students that enroll at least 1 course.
Please help me to find the result. I stuck on that.
can you please try following example:
Model/Student.php //write relationship in your model
public function courses()
{
return $this->belongsToMany(Course::class, 'payment');
}
and then try with following eloquent query
$students = Student::whereHas('courses')
->take(10)
->get();
Try this.
use Illuminate\Database\Eloquent\Model;
class Student extends Model {
public function student_courses() {
return $this->hasMany('App\StudentCourses');
}
}
$students = Student::whereHas('student_courses')->get();

Resources