Question

I'm sure the answer to this is trivial but I've been at it for a long time now and can't find the right combination.

I have 3 tables, Blogs, Posts and Likes. I would like to list the Posts with the most Likes per Blog.

Right now to count the likes per post I'm grouping the query like this (ending up with multiple posts from the same blog):

select
  posts.*,
  count(*) as c
from posts
inner join likes
  on posts.id = likes.post_id
group by posts.id

The relations between the tables are:

Blog: id, name
Post: id, name, content, blog_id
Like: id, post_id
Was it helpful?

Solution 2

I would like to list the Posts with the most Likes per Blog.

Assuming that the posts table contains a blog_id, I think this would satisfy your needs:

SELECT p.id AS post_id, p.blog_id, COUNT(1) AS like_count
FROM posts p
INNER JOIN likes l ON (p.id = l.post_id)
GROUP BY p.id, p.blog_id
ORDER BY COUNT(1) DESC

you didn't specify how many of the top posts per blog you needed, so this will return all of them, in order of the most likes, regardless of which blog the post comes from.

If you only want the top post per blog, then it's considerably more complicated in MySQL:

SELECT v.post_id, v.blog_id, v.like_count 
FROM (
    SELECT p.id AS post_id, p.blog_id, COUNT(1) AS like_count
    FROM posts p
    INNER JOIN likes l ON (p.id = l.post_id)
    GROUP BY p.id, p.blog_id
) v
INNER JOIN (
    SELECT MAX(t.like_count) AS like_count, t.blog_id
    FROM (
        SELECT p.id AS post_id, p.blog_id, COUNT(1) AS like_count
        FROM posts p
        INNER JOIN likes l ON (p.id = l.post_id)
        GROUP BY p.id, p.blog_id
    ) t
    GROUP BY t.blog_id
) max_post ON (max_post.like_count = v.like_count AND max_post.blog_id = v.blog_id);

You can see the fiddle for this, here.

Caveat - if two posts for the same blog share the maximum like count for that blog then they will both appear in the results.

OTHER TIPS

The following query gets the count of likes for posts on a blog:

select p.blog_id, count(*) as numlikes
from posts p inner join
     likes l
     on p.id = l.post_id
group by p.blog_id;

To get the maximum . . . Well, this isn't so much fun in MySQL for an aggregation query. Here is one method that uses substring_index()/group_concat()

select p.blog_id, max(numlikes) as maxnumlikes,
       substring_index(group_concat(p.id order by numlikes desc), ',', 1
                      ) as MostLikedPostId
from (select p.blog_id, p.id, count(*) as numlikes,
      from posts p inner join
           likes l
           on p.id = l.post_id
      group by p.blog_id, p.id
     ) pb;

If you want more information about the post, then you can add an additional join to get the post information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top