Laravel - Nested select (Eloquent) - sql

I have a scores table that I have to group by the attempt_number and take the sum of scores
I want to nest this query using Eloquent and SQL raw and take the Max score from the attempts and order it according to score. I need the final result as a leaderboard.
$usersByScore = Attempt::where('game_id',$id)
->select('user_id','attempt_no','game_id',DB::raw('SUM(score) as total_score'))
->groupBy('attempt_no')
->orderBy('total_score', 'DESC')
->get()
this gives me the leaderboard but it has all attempts from the user. I need just the max score attempt for each user ordered by the score in descending order.

use distinct() method for this: i hope it will work.
$usersByScore = Attempt::where('game_id',$id)
->select('user_id','attempt_no','game_id',DB::raw('SUM(score) as total_score'))
->groupBy('attempt_no')
->orderBy('total_score', 'DESC')
->distict()
->get()

Got the solution - Implemented the from method to nest the query
$usersByScore = Attempt::with('user')
->select(DB::raw('MAX(tscore) as total_score, user_id,attempt_no'))
->from(DB::raw('(SELECT user_id,attempt_no,SUM(score) as tscore FROM
attempts WHERE game_id = '.$id.' GROUP By attempt_no,user_id) AS T'))
->groupBy('user_id')
->get();

Related

Phalcon Model order by item popularity (number of appearances)

I'm sure I have done something like this before, but can't find it and google not being helpful.
Using Phalcon model if possible, I want to select the items from a table whose ID appears the most - i.e. 10 most popular items ordered by popularity. Is this possible using Model::find("conditions")? I do I have to use PHQL for this?
using model::find
Model::find([
'columns' => 'id,count(id) as counter',
'group' => 'id',
'order' => 'counter DESC'
]);
PHQL:
$this->modelsManager->executeQuery('SELECT count(id) AS counter,id FROM ModelName GROUP BY id ORDER BY counter DESC');
find() does have a group clause, but I don't think it's possible to do what you want because you also need to do a count.
Talal's answer is close, but won't work if you want a list of model objects.
Something like this should work:
$Results = $this->modelsManager->executeQuery('SELECT * FROM ModelName GROUP BY id ORDER BY count(id) DESC LIMIT 10');
$Results->setHydrationMode(\Phalcon\Mvc\Model\Resultset::HYDRATE_RECORDS);
Setting the hydration mode may not be necessary, as Phalcon may default to that mode based on the fact the query is asking for *.

how to group_by a query by date and sum 2 others fields

My model looks like this :
class PostMetric(models.Model):
likes = models.IntegerField()
comments = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
I would like to get the sum of likes and comments for each day (note that i need to transform the datetimefield to datefield (probably using Cast?):
date engagement (likes+comments)
2/5/2017 26
3/5/2017 29
I tried to use : Cast, annotate, aggregate and even rawsql and extra/select functions but with no success.
I think that i need to add an aggregation based to this query :
PostMetric.annotate(engagement=Sum('likes') + Sum('comments')).annotate(date_only=Cast('created_at', DateField()))
If you want to emulate a group_by query then you can use the .values method.
PostMetric.objects.values('created_at').annotate(engagement=Count('likes')+Count('comments')

Laravel eloquent query to get the result groupBy(month)

How to get a result with groupBy(month('start_date'))
So far I have
$this->data['earnings'] = DB::table('documents')
->leftJoin('users','users.id', '=', 'documents.users_id')
->leftJoin('users_editors','users_editors.user_id','=','users_id')
->groupBy(month ('start_date'), 'DESC')
->sum('amount')
->get();
I am trying to get earnings for all the editors groupBy month which will take month from start_date to have a groupBy on.
Thanks
In order to use (My)SQL functions you need raw statements, that are not processed and bound by PDO or, in this case, treated as a field name:
->groupBy(DB::raw('month(start_date)'))
In order to make it work as you expect:
->selectRaw('month(start_date) as month, sum(amount) as sum')
->groupBy(DB::raw('month desc'))
// or:
->groupBy('month')
->orderBy('month', 'desc')
->get();

kohana order group by and count

I have orm query like tthis:
$userCountries = ORM::factory('User')
->select(array(DB::expr('countries.code, COUNT("countries.id") as total')))
->join('countries')
->on('user.country_id', '=', 'countries.id')
->group_by('country.name')
->order_by('total', 'DESC')
->find_all();
What i want is country code with total users quantity from country.
I do not know what is wrong here. I spent 3 hours on it with no success.
What is wrong with this query?
Your SELECT Params is wrong
->select('countries.code', array(DB::expr('COUNT("countries.id")', 'total')))
I think the Group by should be
->group_by('countries.name') instead of ->group_by('country.name')
So Your Total Query will look like
$userCountries = ORM::factory('User')
->select('countries.code', array(DB::expr('COUNT("countries.id")', 'total')))
->join('countries')
->on('user.country_id', '=', 'countries.id')
->group_by('countries.name')
->order_by('total', 'DESC')
->find_all();`
Check this out...

OrderBy count appearing in the wrong order in Eloquent Query Builder (Laravel 4)

I have the following query:
public static function artists_most_popular() {
$artists_most_popular = DB::table('artists')
->join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->orderBy(DB::raw('count(*)', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();
return $artists_most_popular;
}
As you can see from the query, I would like the data to appear in descending order by count of the times the artist_id appears in the fanartists table. However, when I use "foreach" and output this data, it appears in ascending order. Any ideas for why this is happening? I used the following query in SQL Pro, and it works as it should:
select *, COUNT(*)
from artists
join fanartists on artists.id = fanartists.artist_id
group by artists.id
order by (COUNT(*)) desc
I have changed the query little bit. Hopefully this will work.
$artists_most_popular = DB::table('artists')
->join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->select(DB::raw('artists.*, fanartists.*, COUNT(*) AS total_artists'))
->orderBy('total_artists', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();
Also if you want your Artists collection to be returned (this pretends your Artists Model is called Artists), and to further enhance Anam's response, you could do something like:
$artists_most_popular = Artists::join('fanartists', 'artists.id', '=', 'fanartists.artist_id')
->select(DB::raw('artists.*, fanartists.*, COUNT(*) AS total_artists'))
->orderBy('total_artists', 'DESC'))
->groupBy('artists.id')
->take(50)
->get();