问题
I currently have a function:
Score::whereIn('site_id', $sites)
->where('type', 1)
->avg('score');
But at the moment, as you can see, it averages out amongst all results within the Scores table. I want to only average out against the most recent row of each $site_id
(the table may not have all $site_id's in the results though).
The table has a created_at
column, which will determine which is the latest one by date/time.
回答1:
Use orderBy('created_at', 'DESC')
and limit your result with take(15)
. That would take the 15 most recent records in your table.
Score::whereIn('site_id', $sites)
->where('type', 1)
->orderBy('created_at', 'DESC')
->take(15)
->avg('score');
Docs on take() and orderBy().
回答2:
You can add groupBy
:
Score::whereIn('site_id', $sites)
->where('type', 1)
->orderBy('created_at', 'desc')
->groupBy('site_id')
->avg('score');
回答3:
I'm not sure that there's an easy way to do this with Laravel's active record style query builder.
All the times I've done something like this it has required a sub-query or a temporary table, because GROUP BY (in MySQL specifically) will honor the ORDER BY AFTER the grouping is complete, which means you can't guarantee pre-group that the value selected for the grouping is the one that conforms to your ORDER BY.
In this case I think you might actually need 2 sub-queries: the first to order the rows for grouping, the second to do the grouping so there is 1 row per site_id, and the final select to do the averaging. If you do just the first sub-query you will end up with an average for each individual site_id, instead of one average for all site_id's.
Here's an example query of what I think you're looking for:
SELECT AVG('score') FROM (
SELECT * FROM (
SELECT * FROM table_name ORDER BY created_at DESC
) AS tbl GROUP BY site_id
) AS tbl2;
That's untested, but I think it's generally correct.
...all this assumes I've interpreted the question correctly, hopefully I did.
I wish I had a better suggestion than 2 sub-queries - if anyone else has a better way of doing this, I'd love to learn something new.
Now, doing this with Laravel's active record style query builder is something I'd have to go look up to see if it's even possible. Might need to just go run the raw query. But I figured I'd post the methodology to see if it's sound before digging in any further.
来源:https://stackoverflow.com/questions/35950100/laravel-eloquent-get-the-most-recent-row-when-using-wherein-function