从一个表中选择来自其他两个表的计数

时间:2016-02-26 19:50:26

标签: mysql sql mariadb

我正在进行一个查询,我从一个名为employee的表中选择all,并希望从另外两个表中计算employee_id,并在2个单独的列中表示计数。

表:

  1. 员工[id等]
  2. 报告[id,employee_id等]
  3. office_report [id,employee_id等]
  4. 到目前为止我所做的是:

    SELECT emp.*, COUNT(rep.id ) no_of_field_reports, COUNT(of_rep.id) no_of_office_reports 
    FROM employee emp
    LEFT JOIN report rep
        ON (emp.id = rep.employee_id) 
    LEFT JOIN office_report of_rep 
        ON (emp.id = of_rep.employee_id) 
    WHERE emp.user_id =7 AND emp.active = 1 
    GROUP BY emp.id, emp.name 
    ORDER BY emp.name ASC
    

    问题是,只要我在BOTH报告表中有报告,计数就会混乱。假设我在报告表中有16个报告,在 office_report 表中有2个报告, no_of_field_reports no_of_office_reports 的计数将变为32.

    我显然错过了一些东西,但由于我不是一个SQL天才,我无法弄清楚是什么。

    请务必解释造成问题的原因,以便我能够从错误中吸取教训并更好地了解这些类型的查询,因为这不是最后一次。

    我想mariaDB,mySQL和SQL的答案一般都是一样的,所以为了引起注意,我添加了所有这些标签..

1 个答案:

答案 0 :(得分:1)

如果您在不同的计数之后(尽管您可能需要调整到PK字段),可能采用一种方法

SELECT emp.*, 
       COUNT(distinct rep.id ) no_of_field_reports, --may need to be on Unique key instead
       COUNT(distinct of_rep.id) no_of_office_reports --may need to be on Unique key instead)
FROM employee emp
LEFT JOIN report rep
    ON (emp.id = rep.employee_id) 
LEFT JOIN office_report of_rep 
    ON (emp.id = of_rep.employee_id) 
WHERE emp.user_id =7 AND emp.active = 1 
GROUP BY emp.id, emp.name 
ORDER BY emp.name ASC

如果您没有在明确的计数之后获得联接之前的计数,那么这可能是正确的方法并提供灵活性。

SELECT emp.*, rep.cnt, of_Rep.cnt 
FROM employee emp
LEFT JOIN (SELECT count(ID) cnt , employee_ID
           FROM REPORT 
           GROUP BY employee_ID) rep
  ON (emp.id = rep.employee_id) 
LEFT JOIN (SELECT count(ID) cnt, Employee_ID      
          FROM office_report 
          GROUP BY employee_ID) of_rep 
  ON (emp.id = of_Rep.employee_id) 
WHERE emp.user_id =7 AND emp.active = 1 
GROUP BY emp.id, emp.name 
ORDER BY emp.name ASC

或使用相关查询(但不是一直支持,例如从此SQL创建实体化视图时)

SELECT emp.*, 
      (SELECT count(ID)
       FROM REPORT 
       WHERE  emp.id = rep.employee_id) Report_Cnt, 
      (SELECT count(ID)
       FROM office_report  of_REP
       WHERE emp.id = of_Rep.employee_id) of_Rep_Cnt
FROM employee emp
WHERE emp.user_id =7 AND emp.active = 1 
GROUP BY emp.id, emp.name 
ORDER BY emp.name ASC