Mysql 使用左联接的不同表中的计数(*)
我有1个用户表和10个保存用户出版物的表(文章、新闻等)。我想在一个查询中显示每个用户拥有多少出版物:Mysql 使用左联接的不同表中的计数(*),mysql,join,count,group-by,Mysql,Join,Count,Group By,我有1个用户表和10个保存用户出版物的表(文章、新闻等)。我想在一个查询中显示每个用户拥有多少出版物: | ID_USER | COUNT(id_article) | COUNT(id_news) | etc... ------------------------------------------------- | 1 | 0 | 3 | | 2 | 2 | 9
| 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
。。。它没有显示正确的信息。。如果我加入所有的rest表,if会显示非常奇怪的结果(第一个用户有数千篇文章,其余的为NULL)
仅使用一个查询显示此信息的正确方式是什么?谢谢大家! 可以对每个表使用子选择而不是左连接。最终的结果将是一样的,但也许这样更清楚
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
另外,如果您只使用每个表的一列,则子选择比多个左联接更好。您的问题是,您是沿着不同的维度联接的,这会为每个用户创建笛卡尔积。@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条新闻,那么每个用户将乘以120000。可能不可行。您需要计算左侧联接表的不同id。例如,
COUNT(DISTINCT articles.id_article)
@AgRizzo您应该将您的评论作为答案发布,请将其作为答案发布;所以其他的可以从中得到帮助。我更喜欢联接而不是相关子查询。@Rahul:你知道在这种情况下,左联接的性能是否比子查询更好吗?另外,它也不是一个完全相关的子查询,不是吗?有了适当的索引(例如在id\u user\u article
上),这个查询的性能可能比聚合查询的性能要好——在MySQL中(其他数据库更擅长聚合)。如果OP关心性能,他/她应该测试这两种方法。我想OP在这些外键上有索引,如果没有,应该有IMHO。我想你比我更清楚地解释了为什么多个左连接并不是获得一列计数的最佳方法。这是一个很好的解决方案。