I have this table in mysql:
student_payment : id, student_class(varchar), student_code(varchar), gender(varchar), amount(float), created_at (timestamp)
Model name is is StudentPayment
What I want to achieve is that:
If student_class is JSS1, it checks the amount paid by each gender and place it in the respective column
If student_class is JSS2, it checks the amount paid by each gender and place it in the respective column
If student_class is SSS1, it checks the amount paid by everyone, both male and female
If student_class is SSS2, it checks the amount paid by everyone, both male and female
It sums everything vertically and horizontally
It groups everything by date (created_at)
I have this query in my Controller, but don't know how to continue
$students = DB::table('student_payment')
->select(
'student_class',
'gender',
'amount',
DB::raw('DATE(created_at) as created_date')
)
->orderByRaw('created_at DESC');
The result I want to achieve is as shown below:
How do I complete this query in the controller to achieve this result. Thanks
Following Code will give you grouping of student payment data,
$payments = DB::table('student_payment')->orderBy('created_at', 'DESC')->get();
$data = [];
foreach ($payments as $payment){
if($payment->gender=="male"){
$data[$payment->student_class]['male'][] = $payment->amount;
}elseif($payment->gender=="female"){
$data[$payment->student_class]['female'][] = $payment->amount;
}
}
Now you can calculate the sum of amounts using array_sum function. For example,
If you want to calculate payment of JSS1 class female student then,
array_sum(data['JSS1']['female']);
This will give the sum of payment. You can calculate like this for other as well.
Related
I have 2 tables, 'Invoice table', and related 'linesInvoice' table.
To simplify it, I will say that the invoice lines table has only the invoice_id field for the relationship and total for the price.
Now, I need to get last invoices, with his totals (totals, is the sum of column 'total' in every line).
I've tried many examples, but none works for me correctly.
Controller:
$lastInvoices = Invoice::latest()
->limit(10)
->with(['invoiceLines'])->get();
Model for relation
public function invoiceLines()
{
return $this->hasMany(InvoiceLines::class, 'invoice_id');
}
The result that I want for example looks like:
[
Invoice_id => 1
total => 500 //Sum of totals in lines of invoice 1
],
[
Invoice_id => 2
total => 300 //Sum of totals in lines of invoice 2
],
I guess I could go through all the invoices and lines in foreachs and make the sum. But I hope it can be done in the same query
You can use withSum method. This method accept the relation method as first argument and column to sum as second argument
$lastInvoices = Invoice::latest()
->limit(10)
->withSum('invoiceLines','your_column_name')
->with(['invoiceLines'])->get();
Laravel 8^
Invoice::with('invoiceLines')->latest()->first()->invoiceLines()->sum('totle');
totle colme table invoiceLines
I am working on three tables: product, delivery and stock. I want that when a product is delivered, its quantity in the stock table increases. So in the controller of the delivery table I wrote this code:
$produit = Produit::find($delivery['produit_id']);
$quantite = $produit->stock->quantite;
$quantite += $delivery['quantite'];
$quantite->save();
but when I make a delivery, the quantity in the stock table does not change.
Simply types in PHP is not by reference, so you have to assign the new value to the Stock object. This is assuming quantite is an integer on the Stock model, which is not totally clear in the code you provided, since you call ->save() on quantite. Remember to save the Stock model instead of quantite.
$stock = $produit->stock;
$stock->quantite = $stock->quantite + $delivery['quantite']
$stock->save();
i am display graph of sum of qty datewise it works but now i want to display graph in which sum of qty of month and year combine selection. My date is stored in format 2020-02-14 and i want to display sum of qty of 2020-02 that is from 2019-02 to 2020-09. I tried lot of works. I am getting graph date wise but now i want to year and month combine
For date selection the query as
$get_details=DB::select('SELECT sum(orders_qty) as sum_of_qty,deliver_date FROM `orders` WHERE deliver_date between ? AND ? GROUP BY deliver_date',[$data['start_date'],$data['end_date']]);
For yearand month selection i need query
I tried like this
$data=$req->all();
$results = DB::table('orders')
->select(DB::raw('DATE_FORMAT(deliver_date,"%y-%m") as deliver_date'),DB::raw('SUM(orders_qty) as sum_of_qty'))
->whereBetween('deliver_date',[$data['start_year_month'],$data['end_year_month']])
->groupBy('deliver_date')
->get();
$date[start_year_month]='2019-02' $date[end_year_month]='2019-05' and actual database date='2019-02-14'
plz need query
First, use %Y-%m instead of %y-%m;
Secondly, you are rewrite your field's name, so group by will not using the name that has been rewritten, you need to specify DB::raw('DATE_FORMAT(deliver_date,"%Y-%m")
So the query like this:
$data=$req->all();
$results = DB::table('orders')
->select(DB::raw('DATE_FORMAT(deliver_date,"%Y-%m") as delivery_date'),DB::raw('SUM(orders_qty) as sum_of_qty'))
->whereBetween(DB::raw('DATE_FORMAT(deliver_date,"%Y-%m")'), [$data['start_year_month'],$data['end_year_month']])
->groupBy(DB::raw('DATE_FORMAT(deliver_date,"%Y-%m")'))
->get();
You can try this!
$results = DB::table('orders')
->select(DB::raw('DATE_FORMAT(deliver_date,"%y-%m") as deliver_date'),DB::raw('SUM(orders_qty) as sum_of_qty'))
->whereBetween('deliver_date',[$data['start_year_month'],$data['end_year_month']])
->groupBy(function ($val) {
return Carbon::parse($val->start_time)->format('y'); });
I have a Laravel 4.2 project where I get data from a SQL DB and I can display onto the page. I can select the single record just fine, but I want to also show the records around the one selected.
For example, I want to show the 5 records above and below the one selected. Im not sure how to do this in Laravel.
$gradschoolrange = MOGRadschool::where('Title', '=', $gradschool)->get();
In the above example $gradschool might be "Test College", it will return that with a value, but I want to show all the other related records around it with those values too. The results should look something like this:
ABC College
Another College
Blah College
Go To College
Test College
Yet Another College
Yo Yo College
College College
Something College
Eating College
As there's no ordering specified in your initial query, I'm assuming you want 5 next/previous records according to primary key (id? - if not, you would obviously need to change that) in the table?
Given that IDs may not be numerically sequential, we can't simply assume that the previous 5 rows will be the ID of the row with title = $gradschool minus 5, so wondered if this might work:
$initial = MOGRadschool::where('Title', $gradschool)->first(); // get the initial row with the title of $gradschool
$result = MOGRadschool::where('id', '<', $initial->id)->take(5)->orderBy('id', 'DESC') // new query getting the previous 5 rows, by ID
->union(MOGRadschool::where('id', '>', $initial->id)->take(5)) // union a second query getting the next 5 rows by ID
->get() // get the result as a collection
->add($initial) // add the initial row to the collection
->sort(); // sort the collection (by id) so that the initial row is in the middle
So the output is a collection containing the initial row in the middle, with up to 5 records either side. You also have the initial row to highlight the output, if you need that.
If you want it based on the IDs, which is what I understand from your issue, something like this should work:
$selectedGradSchool = MOGRadschool::where('Title', '=', $gradschool)->get()->first();
$aboveSelected = MOGRadschool::where('id', '<=', $selectedGradSchool->id)
->orderBy('id', 'desc')
->take('5')
->get();
$belowSelected = MOGRadschool::where('id', '>' $selectedgradSchool->id)
->take('5')
->get();
//Concatenate both results
$schoolRange = $aboveSelected->concat($belowSelected);
Now the collection should look similar to your desired result.
I have 2 models; Post and Rating
The Rating model contains an amount column which specifies how high something has been rated. This is based on 5 star rating so the amount can be a value from 1-5
The Post model has a one to many relation with the rating model and function called Ratings that returns the hasMany.
I'd like to get the 5 latest posts based on the average rating. For the average rating I've created a function that can be seen below
Note: the plural(Ratings) returns the hasMany relation where as the singular(Rating) returns a value which is the average rating
public function Rating(){
return floor($this->Ratings()->avg('rating'));
}
Is it possible to retrieve posts ordered by the avg rating using the Eloquent QueryBuilder?
Currently I'm retrieving all posts and then using the sortBy method on the collection object in order get the ones with the highest average rating. The way I'm doing this can be seen below.
$posts = Post::all();
$posts = $posts->sortByDesc(function ($post, $key) {
return $post->Rating();
});
Now if I'd only want to show 5 I still have to retrieve and sort everything which doesn't seem very resource friendly(In my eyes. I don't have any proof of this or say it is true).
So my question is the following: Is this doable using Eloquent instead of sorting the FULL collection.
Sub question: Will doing this with Eloquent instead of sorting the collection have any impact on efficiency?
You may use query builder
DB::table('post')
->select('post.id', 'AVG(rating.amount)')
->join('rating', 'post.id', '=', 'rating.post_id')
->groupBy('post.id')
->orderByRaw('AVG(rating.amount) DESC');