Mysql 使用COUNT()从3个联接表中获取数据

Mysql 使用COUNT()从3个联接表中获取数据,mysql,sql,count,subquery,left-join,Mysql,Sql,Count,Subquery,Left Join,我在MySql中有以下4个表: 用户: 用户ID 用户名 密码 一些其他的东西 电影: 电影ID 名字 一些其他的东西 收藏(用户和电影之间的多对多关系): 用户ID 电影ID 回顾: 回顾 用户ID 电影ID 一些其他的东西 所以基本上我想要的是从用户那里提取数据,查看和收集并显示某种用户统计数据,比如每个用户留下的评论数量,以及每个用户保存到其收藏中的电影数量。我以为这只是3个表之间的简单连接,但显然我错了 我认为使用COUNT()聚合函数将是最好的主意,因此我开始为user

我在MySql中有以下4个表:

用户

  • 用户ID
  • 用户名
  • 密码
  • 一些其他的东西
电影

  • 电影ID
  • 名字
  • 一些其他的东西
收藏(用户和电影之间的多对多关系):

  • 用户ID
  • 电影ID
回顾

  • 回顾
  • 用户ID
  • 电影ID
  • 一些其他的东西
所以基本上我想要的是从用户那里提取数据,查看和收集并显示某种用户统计数据,比如每个用户留下的评论数量,以及每个用户保存到其收藏中的电影数量。我以为这只是3个表之间的简单连接,但显然我错了

我认为使用COUNT()聚合函数将是最好的主意,因此我开始为user review和user collection进行单独的查询,效果很好,两个查询的结果都是正确的

 SELECT u.userID, username, COUNT(movieID) AS collection_size 
 FROM collection c INNER JOIN USER u ON u.userID=c.userID 
 GROUP BY c.userID


 userID username    collection_size
 7      user        2
 8      user03      6

当试图连接所有三个表时,问题就出现了。我最接近解决这些问题的方法是:

SELECT u.userID, username, COUNT(DISTINCT c.movieID) AS collection_size, COUNT(DISTINCT r.movieID) AS review_count
FROM collection c INNER JOIN USER u ON u.userID=c.userID 
INNER JOIN review r ON r.userID=u.userID
GROUP BY u.userID

userID  username    collection_size review_count
7       user        2               1
8       user03      6               4
结果几乎是正确的,但是您可以看到userID为10的用户丢失了,尽管他留下了一条评论。此查询似乎只选取了至少留下一篇评论的用户,并且他们的收藏中至少有一部电影。我通过向用户10的收藏中添加一部电影来验证这一点。然后他正确地出现在结果中。 如何更改查询以显示至少留下一篇评论的用户或至少在其收藏中有一部电影的用户

基本上,我希望结果是:

userID  username    collection_size review_count
7       user        2               1
8       user03      6               4
10      user05      0               1

看起来此用户没有集合(您的第一次查询没有返回该集合)。您可以从用户表开始使用
LEFT JOIN
s:

SELECT u.userID, u.username, 
    COUNT(DISTINCT c.movieID) AS collection_size, 
    COUNT(DISTINCT r.movieID) AS review_count
FROM usr u 
LEFT JOIN collection c ON u.userID=c.userID 
LEFT JOIN review r ON r.userID=u.userID
GROUP BY u.userID
虽然这样做有效,但效率不高。联接将两侧的行相乘,然后只计算不同的主键值。我认为对于计数,使用两个子查询可以更有效地表达查询:

select u.userid, u.username, 
    (select count(*) from collection c where c.userid = u.userid) as collection_size,
    (select count(*) from review     r where r.userid = u.userid) as review_count
from usr u

看起来此用户没有集合(您的第一次查询没有返回该集合)。您可以从用户表开始使用
LEFT JOIN
s:

SELECT u.userID, u.username, 
    COUNT(DISTINCT c.movieID) AS collection_size, 
    COUNT(DISTINCT r.movieID) AS review_count
FROM usr u 
LEFT JOIN collection c ON u.userID=c.userID 
LEFT JOIN review r ON r.userID=u.userID
GROUP BY u.userID
虽然这样做有效,但效率不高。联接将两侧的行相乘,然后只计算不同的主键值。我认为对于计数,使用两个子查询可以更有效地表达查询:

select u.userid, u.username, 
    (select count(*) from collection c where c.userid = u.userid) as collection_size,
    (select count(*) from review     r where r.userid = u.userid) as review_count
from usr u


使用左连接,我仍然得到了与第一次相同的结果,但经过重组的查询成功了。谢谢!使用左连接,我仍然得到了与第一次相同的结果,但重构的查询成功了。谢谢!