Sum of the values of a particular user for a particular month of a particular year - laravel

I have a table with time stamp, user id, value. I am trying to get sum of the values of a particular user for a particular month of a particular year. This is what I am using:
$data = Laborhrs::all()->where('employee','7')->sum('value');
This is giving me sum of whole data for employee#7. I am looking to get sum of a particular month of a particular year. Say Sum of values of October 2018. What am I missing?

You forgot to add a condition for the year and month, and you don't need to use all() method.
$sum = Laborhrs::where('employee','7')
->whereMonth('timestamp_column_name', 10)
->whereYear('timestamp_column_name', 2018)
->sum('value');
In addition: I saw your several posts, and I think, you don't understand how laravel eloquent and collections work.
All() method returns collection with all results from database, and then you filters them trough collection (I saw it not first time). It is very slow solution.
Better to use conditions with get() (get() should go after conditions), for example:
$data = Laborhrs::where('employee','7')->get();
It will return collection with results that you need, and you don't need to filter them after getting from database. It will be work much faster.
In that situtation you don't need all() and get() methods at all. Eloquent has sum() method, that will calculate sum in database and return value.

Related

GroupBy doesn't show all the data

I have a list of sellers, where everyone paying service charge. I want to show the service charge grouped by year in descending order. The group's year should be in descending order. Like, I inputed data for 2023, 2020, 2021. The group data should show 2023 first then 2021, then 2020. First I tried with
$infos = Commision::all()->groupBy('country');
If I use order first it shows error. I have a previous question here. The I tried with
$infos = DB::table('service_charges')->groupBy('year')->orderBy('year','DESC')->get();
dd($infos);
But its show's only one data of each group. I have 3 data saved here . 2 is from 2021, 1 is from 2020. But the query showing me only one data from each group here.
the GROUP BY SQL statement is used to aggregate data that have the same value for a given column. That means you can only get a single aggregated result of the data for each distinct value in that column (i.e. one value per year in your case).
The collection groupBy is used to group all data in their own collection if they have the same value. However the difference is that groupBy in the collection runs after the query so you can no longer orderBy at that point. Here are two ways you might be able to solve your issue:
Order in the query then group the resulting collection
$infos = DB::table('service_charges')->orderBy('year','DESC')->get()->groupBy('year');
Sort and order the resulting collection
$infos = Commision::all()->groupBy('country')->sortKeysDesc();

How to compare columns in a new column

I have a recordset where rows have a date field.Rows are from current year and last year. I want to see the count of rows per year. That's easy. Now I'd like to have a third column with difference (count(currentYear) - count(lastYear)). Is there any way to achieve this?
thanks
It seems like you want to have the difference calculated between two members of the same date field.
If so, you might want to consider the customizeCell() API call to retrieve the count values of each year, use them to calculate the difference, and modify the necessary cells with the result.
Alternatively, you could try modifying your data set so that the lastYear and currentYear are two different fields – this, for example, would allow you to compare them within a calculated value.

Eloquent ORM get latest items query

I am trying to do get all the latest items and sort by id descending (i.e. get all items that were just added with a limit and offset).
So I did this:
$products = Product::all()
->slice($request->get('offset'))
->take($request->get('limit'))
->sortByDesc('id')
->toBase();
However it seems when I have more that that limit, then I dont have the right order. It gets me say 10 products but not sorted corrected. Any idea how to do this with Eloquent ORM?
You are probably intending to have the database handle the offset and skipping and ordering instead of pulling all the possible records then taking only what you want, then sorting them ... if you were going to do it your way you would need to sort before you skip and take, by the way.
Using the database to the the filtering and ordering:
$products = Product::skip($request->input('offset'))
->take($request->input('limit'))
->orderBy('id', 'desc')
->get();
I think the issue is you're using ::all() first, which returns all Product instances in a Collection, then using collection methods. Since these methods act in order of usage, you're slicing and offsetting before sorting, so you'll get the same products each time. Use proper Builder syntax to handle this properly and more efficiently:
$products = Product::offset($request->input("offset"))
->limit($request->input("limit"))
->orderBy("id", "DESC")
->get();
Because this is a Builder instance, the query will be compiled and executed according to your Database's grammar logic, and in a single query. There's nothing wrong in using Collection logic, you'd simply have to use the correct order of methods (sortByDesc() first, then slice(), then take()), but this is incredibly inefficient as you have to handle every Product in your database.

Eloquent get average for both genders from a collection without requesting again the database

I have this situation where I get a collection directly from the database and have introduced several filters already, except gender, as follows:
$workers = Worker::where('status','Active')->where('category','SomeCategory')->get();
In order to get the general age average, I get it like this:
$avg_age = $workers->avg('age');
So far so good.
Inside, the $workers collection, there is this column gender. Now I want to get the age average by gender. I have tried the following ... which doesn't work:
$avg_age_women = $workers->where('gender','female')->avg();
But this does not work since the returned value is zero.
I know I could do the same like:
$workers_female = Worker::where('status','Active')->where('category','SomeCategory')->where('gender','female')->get();
But, if I can continue working with the $workers collection, I think that'd be more efficient.
Is there a way to get the average of female ones right from the original $workers collection??? What am I missing?
You're not saying what you want to do avg on.
$avg_age_women = $workers->where('gender','female')->avg("age");

Querying a List of objects to find the the day of the week with the most items

There's got to be a better way!
I have a bunch of log records stored in a List. Each log record has a CreateDate field and what I'm trying to do is find an efficient way to query the List object to find the day of the week with the most log records (Monday, Tuesday, etc...).
I'm thinking that this can be done using Linq but I don't know Linq well enough. It may be that I'll have to do this the long way by getting a count for each specific day and then comparing them against each other to find the day with the most logs but I'm hoping that someone will be able to show me a cool way to do it.
Thanks.
Loglist.GroupBy(log => log.CreateDate)
.Select(list => new { DayOfWeek = list.Key.DayOfWeek, Count = list.Count()})
.OrderByDescending(list=>list.Count);
This will return a list of (DayOfWeek, Count) in Descending Order. If you need only the largest count dayofweek, apply .First() at the end of the above list.

Resources