2016-03-09 48 views
1

我不认为这样做太复杂,无法解释,但确实很复杂。SQL:选择多个表的计数

首先,我有几个关于用户意见表,如下图所示每个部分(论坛,文章等),一个表:

site_users(ID,用户名,...)表保存用户的信息]

site_articles_comments(ID,USER_ID,评论,...)[其中USER_ID = site_users.id]

site_forum_comments(ID,USER_ID,评论,...)同为site_articles_comments]

事情是,每一个新行是一个新的评论,用户可以多次评论,这意味着更多的行被添加,从而需要对行数进行排序,以获得某种排序系统中的评论数量。

我能够通过这样简单的查询,使一个简单的论坛等级:

选择u.id,u.username,COUNT(r.id)AS级别FROM site_users为u LEFT JOIN site_forum_comments为R ON u.id = r.user_id GROUP BY u.username, u.id ORDER BY排名DESC LIMIT:L

该查询排序从数据库中,用户谁曾评论最多的所有用户总是在最上面。

另一方面,我需要的是拥有一个全球排名系统,它将每个部分(文章,论坛等)中的评论总数相加并相应地显示用户。

我被玩弄的SQL做到这一点,我想出了最后一件事是这个巨大的查询:

选择u.id,u.username,(COUNT(a.id)+ COUNT(f.id))AS排名从 site_users u左加入site_articles_comments a ON a.user_id = u.id LEFT JOIN site_forum_comments f ON f.user_id = u.id GROUP BY u.username,u.id ORDER BY rank DESC LIMIT:l

但是,返回null。我可能做些什么来实现我想要的结果?

由于提前,

马特乌斯

EDIT1:对不起,缺乏信息,这是关于MySQL的。

+0

还有很多东西需要清理。请明确解释你想要的是什么。 Imean说:**输出示例** @MateusMelo –

+0

如果您至少可以选择我们正在讨论的数据库平台 - 您同时拥有mysql和Oracle标记,那将会更好...... –

回答

0

问题是数学与空值,并与空值排序(签入了“NULLS LAST”选项来覆盖它首先返回空值的降序默认的顺序)。

就你的情况而言,如果用户有大量的文章评论,但没有论坛评论,那么在Oracle数学中100 + null = null。所以为了让数学工作,你需要使null = 0。这就是NVL()进入的地方(也有消除结果集中讨厌的空值的好的副作用)!

SELECT u.id, u.username, (NVL(COUNT(a.id),0) + NVL(COUNT(f.id),0)) AS rank 
FROM site_users u 
    LEFT JOIN site_articles_comments a ON a.user_id = u.id 
    LEFT JOIN site_forum_comments f ON f.user_id = u.id 
GROUP BY u.username, u.id ORDER BY rank DESC LIMIT :l 

我看到你的标签中同时包含MySQL和Oracle--上面是针对Oracle的。如果MYSQL使用COALESCE(COUNT(),0)代替。

+0

谢谢你澄清什么是错的,并对缺乏信息感到抱歉。 –

0

尝试SELECT u.id, MIN(u.username) AS username, (COALESCE(COUNT(DISTINCT(a.id)),0) + COALESCE(COUNT(DISTINCT(f.id)),0)) AS rank FROM site_users AS u LEFT JOIN site_articles_comments AS a ON (a.user_id = u.id) LEFT JOIN site_forum_comments AS f ON (f.user_id = u.id) GROUP BY u.id ORDER BY rank DESC LIMIT :l

+0

好的答案...! ! **建议:**当你有一段代码。尝试在该块的上方和下方留下一行,并在每行代码上放置4个空格。所以它得到一个更可读/可呈现的形式。 –

+0

好吧;)我正在寻找如何做... –

+0

您先生确实救了我的一天,谢谢! –