【问题标题】:Count from 4 tables with join and null values从具有连接和空值的 4 个表中计数
【发布时间】:2021-08-29 05:45:56
【问题描述】:

表格:

 Posts           Comments           Likes            Users
ID | User_id     ID | Post_id      ID | Post_id     ID | Name
-------          --------          --------         --------
1  | 101          1 | 1             1 | 3          101 | 'Michael'
2  | 101          2 | 3             2 | 3          202 | 'Daniel'
3  | 303          3 | 3             3 | 3          303 | 'Scott'

我希望查询的是:

ID | Total_comments | Total_likes | Name
1  |       1        |     0       | 'Michael'
2  |       0        |     0       | 'Michael'
3  |       2        |     3       | 'Scott'

但这是我得到的:

ID | Total_comments | Total_likes | Name
1  |       1        |     0       | 'Michael'
2  |       0        |     0       | 'Michael'
3  |       6        |     6       | 'Scott'

使用此查询:

SELECT Posts.ID,
       COUNT(Comments.Post_id) as Total_comments, 
       COUNT(Likes.Post_id) as Total_likes,
       Users.Name
       FROM Posts INNER JOIN Users 
       ON Users.ID = Posts.User_id 
       LEFT JOIN Comments 
       ON Comments.Post_id = Posts.ID 
       LEFT JOIN Likes 
       ON Likes.Post_id = Posts.ID 
       GROUP BY Posts.ID

我想知道,上面的查询可以通过什么方式修改以返回预期的结果?实现这一目标的好方法是什么?

【问题讨论】:

    标签: mysql sql database count left-join


    【解决方案1】:

    您正在沿两个维度加入,因此您得到的是笛卡尔积。这就是发生的事情。

    一个 hacky 解决方案——如果给定的帖子没有太多的 cmets 和喜欢,效果很好——是使用COUNT(DISTINCT)

    SELECT Posts.ID,
           COUNT(DISTINCT Comments.Post_id) as Total_comments, 
           COUNT(DISTINCT Likes.Post_id) as Total_likes,
           Users.Name
    

    不过,最有效的解决方案可能是相关子查询:

    SELECT p.ID,
           (SELECT COUNT(*) FROM Comments c WHERE c.Post_Id = p.ID) as Total_comments, 
           (SELECT COUNT(*) FROM Likes l WHERE l..Post_id = p.ID) as Total_likes,
           u.Name
    FROM Posts p INNER JOIN
         Users u
         ON u.ID = p.User_id ;
    

    这样更快,因为它避免了外部聚合。但是,它需要comments(post_id)likes(post_id) 上的索引。

    【讨论】:

    • 这有帮助!感谢您的见解!
    • @Vytausek 如果您觉得答案有用,请考虑接受和/或支持它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-22
    • 2017-08-30
    • 2023-03-27
    相关资源
    最近更新 更多