使用LEFT JOIN的COUNT(*)来自不同的表

时间:2014-02-22 12:40:35

标签: mysql join count group-by

我有1个用户表,10个表(文章,新闻,...),我保存用户的出版物。我想在一个查询中显示每个用户有多少出版物:

| ID_USER | COUNT(id_article) | COUNT(id_news) | etc...
-------------------------------------------------
| 1       | 0                 | 3               |
| 2       | 2                 | 9               |
| 3       | 14                | 5               |
| 4       | 0                 | 0               |

如果我使用此查询来显示文章数量......

SELECT id_user,COUNT(articles.id_article) FROM users 
LEFT JOIN articles ON articles.id_user_article=users.id_user 
GROUP BY users.id_user

...它正确显示信息。但是如果我开始添加第二张表......

    SELECT id_user,COUNT(articles.id_article),COUNT(news.id_news) FROM users 
    LEFT JOIN articles ON articles.id_user_article=users.id_user
    LEFT JOIN news ON news.id_user_news=users.id_user 
    GROUP BY users.id_user

...它没有显示正确的信息..如果我加入所有其余的表,如果显示非常奇怪的结果(第一个用户有数千篇文章,其余的则为NULL)。

使用一个查询显示此信息的正确方法是什么?谢谢!

2 个答案:

答案 0 :(得分:1)

您可以为每个表使用子选择而不是左连接。最终的结果将是相同的,但也许这样更清楚。

SELECT u.id_user, 
  (SELECT COUNT(a.id_article) 
  FROM articles a 
  WHERE a.id_user_article = u.id_user) AS articles,
  (SELECT COUNT(n.news) 
  FROM news n  
  WHERE n.id_user_news = u.id_user) AS news
FROM users u

此外,如果您只使用每个表的一列,则子选择比多个左连接更好。

答案 1 :(得分:1)

您的问题是您正在加入不同的维度,这会为每个用户创建笛卡尔产品。 @rafa的解决方案实际上是MySQL的一个很好的解决方案。使用count(distinct)可以正常工作,但只有当计数不是很大时才可以。另一种方法是沿每个维度预先汇总结果:

SELECT u.id_user, a.articles, n.news
FROM users u left outer join
     (select id_user_article, count(*) as articles
      from articles
      group by id_user_article
     ) a
     on u.id_user = a.id_user_article left outer join
     (select id_user_news, count(*) as news
      from news
      group by id_user_news
     ) n
     on u.id_user = n.id_user_news;

编辑:

如果您使用的是count(distinct)方法,那么您将生成一个交叉产品。如果每个用户有3篇文章和4个新闻项,那么用户将乘以12.可能是可行的。

如果每个用户有300篇文章和400个新闻项,那么每个用户将乘以120,000。可能不可行。