Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL group by and inner join

I have an article table which holds the number of articles views for each day. A new record is created to hold the count for each seperate day for each article.

The query below gets the article id and total views for the top 5 viewed article id for all time :

SELECT article_id, 
SUM(article_count) as cnt
FROM article_views
GROUP BY article_id
ORDER BY cnt DESC
LIMIT 5 

I also have a seperate article table which holds all the article fields. I want to ammend the query above to join to the article table and get two fields for each article id. I have tried to do this below but count is comming back incorrectly :

SELECT article_views.article_id, SUM( article_views.article_count ) AS cnt, articles.article_title, articles.artcile_url
FROM article_views
INNER JOIN articles ON articles.article_id = article_views.article_id
GROUP BY article_views.article_id
ORDER BY cnt DESC
LIMIT 5

Im not sure exactly what im doing wrong. Do I need to do a subquery?

like image 452
user1052096 Avatar asked Jan 24 '13 16:01

user1052096


People also ask

Can I use inner join and GROUP BY together?

Using Group By with Inner JoinSQL Inner Join permits us to use Group by clause along with aggregate functions to group the result set by one or more columns.

Is join and inner join same in MySQL?

In MySQL, JOIN , CROSS JOIN , and INNER JOIN are syntactic equivalents (they can replace each other). In standard SQL, they are not equivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise. In general, parentheses can be ignored in join expressions containing only inner join operations.

Can we use both GROUP BY and order by together in SQL?

Using Group By and Order By Together When combining the Group By and Order By clauses, it is important to bear in mind that, in terms of placement within a SELECT statement: The GROUP BY clause is placed after the WHERE clause. The GROUP BY clause is placed before the ORDER BY clause.

Can we use 2 GROUP BY in MySQL?

Yes, it is possible to use MySQL GROUP BY clause with multiple columns just as we can use MySQL DISTINCT clause.


2 Answers

Add articles.article_title, articles.artcile_url to the GROUP BY clause:

SELECT 
  article_views.article_id, 
  articles.article_title, 
  articles.artcile_url,
  SUM( article_views.article_count ) AS cnt
FROM article_views
INNER JOIN articles ON articles.article_id = article_views.article_id
GROUP BY article_views.article_id,   
         articles.article_title, 
         articles.artcile_url
ORDER BY cnt DESC
LIMIT 5;

The reason you were not getting correct result set, is that when you select rows that are not included in the GROUP BY nor in an aggregate function in the SELECT clause MySQL picks up random value.

like image 141
Mahmoud Gamal Avatar answered Sep 24 '22 14:09

Mahmoud Gamal


You are using a MySQL (mis) feature called Hidden Columns, because article title is not in the group by. However, this may or may not be causing your problem.

If the counts are wrong, then I think you have duplicate article_id in the article table. You can check this by doing:

select article_id, count(*) as cnt
from articles
group by article_id
having cnt > 1

If any appear, then that is your problem. If they all have different titles, then grouping by the title (as suggested by Mahmoud) would fix the problem.

If not, one way to fix it is the following:

SELECT article_views.article_id, SUM( article_views.article_count ) AS cnt, articles.article_title, articles.artcile_url
FROM article_views INNER JOIN
     (select a.* from articles group by article_id) articles
     ON articles.article_id = article_views.article_id
GROUP BY article_views.article_id
ORDER BY cnt DESC
LIMIT 5

This chooses an abitrary title for the article.

like image 28
Gordon Linoff Avatar answered Sep 25 '22 14:09

Gordon Linoff