I switched from NOSQL to SQL and i can’t find how to select the max of count(*)
i created users table, posts and comments. i want to select TOP 10 users with the max of posts and max of comments
SELECT fullname, (SELECT COUNT(*) FROM posts WHERE posts.author_id = users.id) AS total_posts, (SELECT COUNT(*) FROM comments WHERE comments.author_id = users.id) AS total_comments FROM usersAdvertisement
Answer
First, using SQL database require you to define the JOIN statement between the associated tables to get the referenced relationship data.
Since you require to get TOP 10 user with most posts, using traditional approach with LIMIT 10 will have problem when users have the same post count and should be considered the same rank. E.g: 4 people have 5 posts, 3 people have 6 posts..
To solve the same post count problem above, we will choose RANK query, this will treat people with the same post count as the same rank.
SELECT users.fullname, posting_rank_stats.total_posts, posting_rank_stats.posting_rankFROM usersINNER JOIN( SELECT author_id, total_posts, RANK() OVER (ORDER BY post_author_count.total_posts DESC) AS posting_rank FROM ( SELECT COUNT(*) AS total_posts, author_id FROM posts GROUP BY author_id ) post_author_count) posting_rank_statsON users.id = posting_rank_stats.author_id-- we only want to search for top 10WHERE posting_rank_stats.posting_rank <= 10;Breaking to small pieces:
1.Get post count for each user
First, we get the post count for each user, this require the COUNT function, and GROUP BY author_id
SELECT COUNT(*) AS total_posts, author_idFROM postsGROUP BY author_id2. Calculating the rank of post count
Use the RANK() function to calculate the rank of the post. Ranking positition is determined by the highest number of total_posts
SELECT author_id, total_posts, RANK() OVER (ORDER BY post_author_count.total_posts DESC) AS posting_rankFROM( SELECT COUNT(*) AS total_posts, author_id FROM posts GROUP BY author_id) post_author_count3. Wrap up
The last step is joining the users table with the posting_rank_stats table to get the result. Since we only want to get in the TOP 10 user with most post, so you will need to add the condition
posting_rank_stats.posting_rank <= 10 in the WHERE clause
Apply the same concept to get comment rank also.
Here is the db fiddle I created, combine both posting rank and commenting rank
SELECT users.id , users.fullname, posting_rank_stats.posting_rank , posting_rank_stats.total_posts, commenting_rank_stats.comment_rank, commenting_rank_stats.total_commentsFROM usersLEFT JOIN( SELECT author_id, total_posts, RANK() OVER (ORDER BY post_author_count.total_posts DESC) AS posting_rank FROM ( SELECT COUNT(*) AS total_posts, author_id FROM posts GROUP BY author_id ) post_author_count ) posting_rank_stats ON users.id = posting_rank_stats.author_idLEFT JOIN( SELECT author_id, total_comments, RANK() OVER (ORDER BY comment_author_count.total_comments DESC) AS comment_rank FROM ( SELECT COUNT(*) AS total_comments, author_id FROM comments GROUP BY author_id ) comment_author_count) commenting_rank_stats ON users.id = commenting_rank_stats.author_id;| id | fullname | posting_rank | total_posts | comment_rank | total_comments |
|---|---|---|---|---|---|
| 1 | Jackson | 1 | 3 | 5 | 1 |
| 2 | Marry | 4 | 1 | 1 | 5 |
| 3 | Josh | 4 | 1 | 2 | 3 |
| 4 | Harley | 1 | 3 | 4 | 2 |
| 5 | Gordon | 4 | 1 | 5 | 1 |
| 6 | Barney | 4 | 1 | 2 | 3 |
| 7 | Gman | 4 | 1 | ||
| 8 | Stephan | 3 | 2 | ||
| 9 | Lucy | ||||
| 10 | Jordan | ||||
| 11 | Bill | ||||
| 12 | Rosh | ||||
| 13 | Lee |