如何通过LEFT JOIN添加多个表并计算每个表的行数?

时间:2017-11-13 13:41:34

标签: mysql

我正在计算我左下角的表格的结果:

SELECT p.*,COUNT(po.name) AS posts
    FROM projects p
    left join posts po on p.name = po.name
    group by p.id

http://sqlfiddle.com/#!9/3e9d4b/4

enter image description here

但现在我想通过LEFT JOIN添加另一个表并计算它:

SELECT p.*,COUNT(po.name) AS posts,
    COUNT(ta.name) AS tasks
    FROM projects p
    left join posts po on p.name = po.name
    left join tasks ta on p.name = ta.name
    group by p.id

http://sqlfiddle.com/#!9/ee068/2

enter image description here

但现在计算错了。对于猫我只有2个帖子和3个任务。 6号来自哪里?

2 个答案:

答案 0 :(得分:2)

左连接不是正确的工具。您应该使用子选择:

SELECT p.*,
  (SELECT COUNT(*) FROM posts po WHERE p.name = po.name) AS posts,
  (SELECT COUNT(*) FROM tasks ta WHERE p.name = ta.name) AS tasks
FROM projects p

答案 1 :(得分:1)

您仍然可以使用联接,但您可以在不同的子查询中聚合两个表中的每一个,而不是单个顶级聚合:

SELECT
    p.name,
    COALESCE(t1.posts_cnt, 0) AS posts_cnt,
    COALESCE(t2.tasks_cnt, 0) AS tasks_cnt
FROM projects p
LEFT JOIN
(
    SELECT name, COUNT(*) AS posts_cnt
    FROM posts
    GROUP BY name
) t1
    ON p.name = t1.name
LEFT JOIN
(
    SELECT name, COUNT(*) AS tasks_cnt
    FROM tasks
    GROUP BY name
) t2
    ON p.name = t2.name

您当前的查询存在问题,因为您按id聚合,但选择了其他列。根据我的看法,您希望使用name列聚合所有三个表。

这种方法应该优于使用相关子查询的方法。