SQL Self使用空值连接

时间:2014-09-26 05:56:59

标签: mysql sql

我将所有员工(经理和员工)都放在一张名为Employee的桌子下。表格如下,

表格

+-------+------------+---------+---------+------------+
|emp_id | name       | dept_id | salary  | manager_id |
+=======+============+=========+=========+============+
|  1    | Sally      |   1     | 20000   |  null      |
|  2    | Ajit       |   2     | 20000   |   1        |
|  3    | Rahul      |   1     | 20000   |   1        |
|  4    | uday       |   1     | 20000   |   null     |
|  5    | john       |   1     | 20000   |   null     |
|  6    | netaji     |   2     | 20000   |    2       |
|  7    | prakriti   |   3     | 1111    |    3       |
|  8    | sachin     |   3     | 1111    |    3       |
|  9    | santosh    |   1     | 1111    |    2       |
|  10   | Ravi       |   1     | 1111    |    2       |
+-------+------------+---------+---------+------------+

经理和员工都属于同一张桌子。 manager_id是指= emp_id谁是经理。

我想编写查询来计算属于每个经理的员工数量。因此,即使某位经理没有任何雇员在他或她之下,计数也会显示为0

结果应如下,

预期输出

+------+----------+
|Count |  Manager |
+======+==========+
| 2    |  Sally   |
| 3    |  Ajit    |
| 2    |  Rahul   |
| 0    |  Uday    |
| 0    |  John    |
+------+----------+

7 个答案:

答案 0 :(得分:4)

您需要在桌面上进行左连接。左连接将确保每个经理都有一行,即使他们下面没有员工。如果经理没有员工,您需要在联接的员工一侧使用COUNT()汇总NULLCOUNT()实际上并不计算NULL,因此这应该为您提供所需的零。

此查询中的WHERE子句通过查看其manager_id是否为NULL或者连接表中是否存在任何匹配来定义管理员,这意味着有人将其设置为其经理。< / p>

SELECT mgr.name, COUNT(emp.emp_id) AS employee_count
FROM Employee AS mgr
LEFT JOIN Employee AS emp ON emp.manager_id=mgr.emp_id
WHERE mgr.manager_id IS NULL OR emp.emp_id IS NOT NULL
GROUP BY mgr.name

答案 1 :(得分:2)

正确的解决方案可能涉及修复方案,因为任何方法失败为“子管理员”(谁管理,因此有一个manager_id)但不目前管理任何人。

无论如何,如果上述限制是可以接受的,那么人们就是经理如果

  • 他们有一个NULL manager_id(如评论中所述),
  • 他们目前管理其他员工

然后可以使用此查询(示例sqlfiddle):

SELECT m.name as Manager, COUNT(e.id) as `Count`
FROM employee m
LEFT JOIN employee e
ON m.id = e.manager_id
GROUP BY m.id, m.name, m.manager_id
HAVING `Count` > 0 OR m.manager_id IS NULL

注释/解释:

  • LEFT [OUTER]加入在这里很重要;否则将找不到管理任何人的管理人员。然后通过分组结果上的HAVING子句应用过滤。

  • COUNT应用于特定列,而不是*;完成后,该列中的NULL值不计算。在这种情况下,这意味着没有匹配(e)的雇员(m)不会被HAVING中的COUNT条件自动选择。 (LEFT JOIN离开左侧记录,即使没有连接匹配 - 在这种情况下,所有右侧列都是NULL。)

  • GROUP BY包含所有分组字段,即使它们看起来是多余的。例如,这允许在HAVING中使用manager_id字段。 (ID上的组是在两个经理具有相同名称的情况下完成的,或者是在输出子句中选择的。)

答案 2 :(得分:1)

这是解决方案;你要在员工桌上自我加入。

  SELECT e1.manager_id, e2.name, COUNT (1) AS COUNT
    FROM Employee e1 JOIN Employee e2 ON e1.manager_id = e2.id
GROUP BY e1.manager_id, e2.name
UNION ALL
SELECT e3.id, e3.name, 0 AS COUNT
  FROM Employee e3
 WHERE     manager_id IS NULL
       AND e3.id NOT IN (  SELECT e1.manager_id
                             FROM    Employee e1
                                  JOIN
                                     Employee e2
                                  ON e1.manager_id = e2.id
                         GROUP BY e1.manager_id, e2.name)

答案 3 :(得分:0)

也许有帮助:

select t1.name, count(*) -- all managers with emps
  from t t1
  join t t2
    on t1.emp_id = t2.manager_id 
 group 
    by t1.name
 union
   all
select t1.name, 0  -- all managers without emps
  from t t1
  left
  join t t2
    on t1.emp_id = t2.manager_id
 where t1.manager_id is null 
   and t2.emp_id is null

答案 4 :(得分:0)

尝试以下:

select (select count(*) from employees b where b.manager_id = a.emp_id)) as Count, a.Name as manager from  employees a where a.emp_id in (select distict c.manager_id from employees c)

答案 5 :(得分:-1)

<强>查询

CREATE TABLE employee(emp_id varchar(5) NOT NULL,  
emp_name varchar(20) NULL,  
dt_of_join date NULL,  
emp_supv varchar(5) NULL,  
CONSTRAINT emp_id PRIMARY KEY(emp_id) ,  
CONSTRAINT emp_supv FOREIGN KEY(emp_supv)   
REFERENCESemployee(emp_id));  

答案 6 :(得分:-1)

你需要做的 LEFT OUTER JOIN喜欢这样:

SELECT movies.title,sequelies.title AS sequel_title
FROM movies
LEFT OUTER JOIN movies sequelies
    ON movies.sequel_id = sequelies.id ;