How to Compare Two Column as Condition in Eloquent Laravel - laravel

I want to compare two column as condition in Eloquent Laravel.
For example:
I have 3 columns, qty_1, qty_2, and price.
I wanto to get product which price under 1000 if column qty_1 and qty_2 are equal.
I have tried these codes but not working:
Product::whereColumn('qty_1','=','qty_2', function($query){
return $query->where('price','<', 1000);
});
How to do that?
Thank you.

Try this :
Product::whereColumn('qty_1','qty_2')
->where('price','<',1000)
->get();

Related

Laravel 8 Sum column of related table

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

Display result in graph based on combination of year and month selection in laravel

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'); });

Is it possible to sort the results of a select by relationships

Is it possible to sort the results of a select by relationships?
I have a one to many relationship. A product has multiple items. And each item has a price. I need to fetch the products, however the ordering of the products must be for the price of the items
Let me give you an example:
Product::with(['items'])->whereHas('items', function ($query) {
$query->orderBy('price', 'desc')
})->get();
It would be something like that. But I need to sorting the products per prices that are inside the items.
if my database has the following:
product 1
item $ 1.2
item $ 2.0
product 2
item $ 3.0
item $ 0.5
product 3
item 1.0
I need a return:
product 2
item $ 3.0
item $ 0.5
product 3
item 1.0
product 1
item $ 1.2
item $ 2.0
because it was considered the lowest item of each product. How could I do this query using enloquent?
can you try this on your query.
Product::withCount(['items as ItemTotalAmount' => function($q){
$q->select(DB::raw("SUM(price)"));
}])
->with('items')
->orderBy('ItemTotalAmount', 'ASC')->get();
In this query, it sum first the Items Price and put the Total in the Alias ItemTotalAmount
Then I used orderBy in the ItemTotalAmount to sort the products that has more total of items price.
whereHas is typically used to query relationship existence with additional where() conditions. From the documentation:
If you need even more power, you may use the whereHas and orWhereHas
methods to put "where" conditions on your has queries. These methods
allow you to add customized constraints to a relationship constraint.
In your particular case, you just want to order the eager-loaded relations. As such, the following should do the trick instead.
$product = Product::with(['items' => function($query) {
$query->orderBy('price', 'asc');
}])
->get();

Laravel get row with records above and below it

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.

Laravel groupBy take n groups

Let's say I have a table users with thousands of records, each with their name.
My goal is to draw a pie chart showing the most common names. I want to take, for example, the 9 most common names, and put the rest into a 'others' group.
I can't figure out how to use groupBy() and take(), or whatever, to achieve this.
Any ideas?
You can try using groupBy and count raw
$groups = DB::table('users')
->select(DB::raw('count(*) as user_count, name'))
->groupBy('name')
->orderBy('user_count', 'desc') //lorder desc or asc
->limit(5) //number of groups
->get();
dd($groups); you will see the user_count and name
Data for your pie chart would be user_count/total_user

Resources