MYSQL group by和inner join

时间:2013-01-24 16:05:01

标签: mysql subquery inner-join

我有一个文章表,其中包含每天的文章数量。创建新记录以保存每篇文章的每个单独日期的计数。

以下查询获取所有时间前5个已查看文章ID的文章ID和总观看次数:

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

我还有一个单独的文章表,其中包含所有文章字段。我想修改上面的查询以加入文章表并为每个文章ID获取两个字段。我试图在下面这样做,但是计数回复不正确:

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

我不确定我到底做错了什么。我需要做一个子查询吗?

3 个答案:

答案 0 :(得分:10)

articles.article_title, articles.artcile_url添加到GROUP BY子句:

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;

您没有获得正确结果集的原因是,当您选择GROUP BY中未包含的行或SELECT子句中的聚合函数时,MySQL会选择随机值。< / p>

答案 1 :(得分:3)

您正在使用名为隐藏列的MySQL(错误)功能,因为文章标题不在group by中。但是,这可能会也可能不会导致您的问题。

如果计数错误,那么我认为您在文章表中有重复article_id。您可以通过执行以下操作来检查:

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

如果出现,那就是你的问题。如果它们都有不同的标题,那么按标题分组(按照Mahmoud的建议)将解决问题。

如果没有,一种解决方法如下:

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

这会为文章选择一个abitrary标题。

答案 2 :(得分:0)

您的查询对我来说基本上是正确的......

但是cnt返回的值将取决于article_id表中articles列为UNIQUE的列。我们假设它是主键,并且缺少模式定义,这只是一个假设。)

此外,我们可能会假设表之间存在外键,即article_id表中没有articles_view的值与{{article_id的值不匹配1}}来自articles表的一行。


要检查“orphan”article_id值,请运行如下查询:

SELECT v.article_id
  FROM articles_view v
  LEFT
  JOIN articles a
    ON a.article_id = v.article_id
 WHERE a.article_id IS NULL

要检查文章中的“重复”article_id值,请运行如下查询:

SELECT a.article_id
  FROM articles a
 GROUP BY a.article_id
HAVING COUNT(1) > 1 

如果其中任何一个查询返回行,则可能是您观察到的行为的解释。