Mysql ';cmt的数量';是4而不是2。为什么?
我有4张桌子: 用户(id、姓名、电子邮件) 论文(id、标题、内容、作者) 评级(id、paperId、star) 评论(id、paperId、msg) 我要获取字段:papers.id、papers.title、papers.content、users.name、, 平均(评级.星级),计数(评论.味精) 我执行一个查询,如:Mysql ';cmt的数量';是4而不是2。为什么?,mysql,sql,left-join,Mysql,Sql,Left Join,我有4张桌子: 用户(id、姓名、电子邮件) 论文(id、标题、内容、作者) 评级(id、paperId、star) 评论(id、paperId、msg) 我要获取字段:papers.id、papers.title、papers.content、users.name、, 平均(评级.星级),计数(评论.味精) 我执行一个查询,如: SELECT papers.id, papers.title, papers.content, users.name, AVG(rating.star) AS avg
SELECT papers.id, papers.title, papers.content, users.name,
AVG(rating.star) AS avg_star , COUNT(comments.msg) AS num_of_cmt
FROM papers
JOIN users ON users.id = papers.created_by
LEFT JOIN rating ON rating.paperId = papers.id
LEFT JOIN comments ON comments.paperId = papers.id
WHERE papers.id = 1
那么结果在“num\u of_cmt”字段为false:
上面的“num_of_cmt”是4而不是2。为什么?评级和评论都有多行
paperid=1
。因此,连接这些表将产生四个结果,其ID如下:
ratings comments
1 1
1 5
5 1
5 5
因此,计数为4。您可以通过执行count(distinct comments.id)
来修复计数。然而,平均值将会下降
解决此问题的一种方法是在子查询中聚合
评级
和注释
。与您离开联接一个表的方式相同,只不过这样做了四次。如果您想让我们解决您的实际问题,请将其放在标题中,而不是询问如何联接四个表(因为这与您在文章正文中提出的问题截然不同)。如果显示所有字段,您将看到重复的行。这是因为联接是跨积操作。您可以使用嵌套查询和分组方式获得正确的计数,而不是实际计数的倍数。按paperId分组评级和注释,聚合然后加入。
id | paperId | star
1 | 1 | 2
2 | 2 | 4
3 | 3 | 4
4 | 2 | 2
5 | 1 | 3
id | paperId | msg
1 | 1 | abcd
2 | 2 | xxxx
3 | 2 | yyyy
4 | 3 | zzzz
5 | 1 | tttt
6 | 4 | kkkk
SELECT papers.id, papers.title, papers.content, users.name,
AVG(rating.star) AS avg_star , COUNT(comments.msg) AS num_of_cmt
FROM papers
JOIN users ON users.id = papers.created_by
LEFT JOIN rating ON rating.paperId = papers.id
LEFT JOIN comments ON comments.paperId = papers.id
WHERE papers.id = 1
id title content name avg_star num_of_cmt
1 This is title 1 This is content 1 ABC 2.5000 4
ratings comments
1 1
1 5
5 1
5 5