Reputation: 1811
I have a table with articles
and two pivot tables views
and votes
for articles that have columns article_id
and user_id
. For articles I have a column publish
where I check if the article is published. I need to make a query by popularity, where I get all the published articles with their count from both pivot tables, where each vote from the table votes
counts
as 3
, and each count from the table views
counts
as 1
. Not sure how to do this, I previously had a query where I was getting published articles with their count of only votes, but I was only getting the articles that had some votes, and not the ones that were published but had no votes. And in the new query I need to add views as well, and change the logic for counting as well as including the articles that are published and not views and order them by their count from these two pivot tables.
So, the wanted output would something like this:
[{"id":117,"popularityCount":17},{"id":118,"popularityCount":15},{"id":121,"popularityCount":13}]
This was the query, but that is not what I need anymore:
$articles = DB::table('articles')
->select([DB::raw('articles.id'), DB::raw('COUNT(*) as "votes"')])
->join('votes', 'article_id', '=', 'articles.id')
->where('articles.publish', 1)
->groupBy('votes.article_id')
->orderBy('votes', 'desc')
->get();
return $articles;
Upvotes: 1
Views: 131
Reputation: 1811
This is what worked for me in the end if anyone will need it in the future!
$result = Article::select('articles.*', 'v.vote_count', 'vw.view_count')
->where('publish', 1)
->leftJoin(DB::raw('(SELECT votes.article_id, COUNT(*) AS vote_count FROM votes GROUP BY votes.article_id) v'), 'v.article_id', '=', 'articles.id')
->leftJoin(DB::raw('(SELECT views.article_id, COUNT(*) AS view_count FROM views GROUP BY views.article_id) vw'), 'vw.article_id', '=', 'articles.id')
->orderByRaw('(v.vote_count * 3) + vw.view_count DESC')
->where('created_at', '>', $date->format('Y-m-d') . ' 00:00:00')
->get();
Upvotes: 0