使用涉及外键的count进行查询

时间:2014-01-06 03:17:04

标签: mysql sql

在查询中,我从三个表中获取数据:companyclasses_by_companyperson。我在名为company_id的所有表中都有一个外键。我使用左连接来使用匹配的company_id对表进行网格化。我试图找出每个公司和员工的课程数量。我得到的值都不正确。这是SQIDDLE

SELECT a.id, 
a.company_id,
a.status,
COUNT(c.company_id) AS classes_per_company,
COUNT(p.employee_id) AS employees_per_company
FROM company a
LEFT JOIN classes_by_company c
ON a.company_id = c.company_id
LEFT JOIN person p
ON a.company_id = p.company_id
GROUP BY a.company_id

表格结构:

CREATE TABLE company
    (
     id int auto_increment primary key,
     company_id int,
     status varchar(20)
    );
CREATE TABLE classes_by_company
(
 id int auto_increment primary key,
 company_id int,
 class_name varchar(20)
);
CREATE TABLE person
(
 id int auto_increment primary key,
employee_id int,
 company_id int,
 person_name varchar(20)
);

enter image description here

2 个答案:

答案 0 :(得分:2)

我不得不问 - 为什么company同时拥有company_id id?其中一个不应该足够吗?无论如何,你的问题是由于连接的乘法性质 - 也就是说,如果公司有2名员工,2个班级,你最终会得到4行 - 每个组合1个(A + A级,人A + B级,B + A级,B + B级)。因此,这是通常解决问题的另一种方式:

SELECT a.id, a.company_id, a.status,
       c.count AS classes_per_company,
       p.count AS employees_per_company
FROM company a
LEFT JOIN (SELECT company_id, COUNT(*) as count
           FROM classes_by_company
           GROUP BY company_id) c
       ON a.company_id = c.company_id
LEFT JOIN (SELECT company_id, COUNT(*) as count
           FROM person
           GROUP BY company_id) p
       ON a.company_id = p.company_id

(以及resulting fiddle - 感谢您提供一个!)

请注意,虽然两个答案都给出了正确的结果,但这个版本的性能可能更高,因为它有更高的机会使用索引。

答案 1 :(得分:1)

我认为您需要COUNT(DISTINCT c.company_id),因为您的数据包含相同company_id和类的条目

SELECT a.id, 
       a.company_id,
       a.status,
       COUNT(DISTINCT c.id) AS classes_per_company,
       COUNT(DISTINCT p.employee_id) AS employees_per_company
FROM company a
LEFT JOIN classes_by_company c ON a.company_id = c.company_id
LEFT JOIN person p ON a.company_id = p.company_id
GROUP BY a.id,a.company_id,a.status

根据您更新的问题:您只需要COUNT(DISTINCT p.employee_id)

我认为您应该COUNT(DISTINCT c.id)代替COUNT(c.company_id),因为您正在尝试计算课程,而不是公司。