MySQL从树状结构中查询计数键

时间:2015-06-17 08:52:27

标签: mysql database

我有三张桌子:

 Department(ID,name) , 
 SubDepartment(parentID,childID) and 
 Department_Employees(idEmployee, idDepartment)
  1. 在表“Department_Employees”中,idDepartment是外键链接的 到“部门”表的ID。
  2. 在表“SubDepartment”中,parentID和childID是外键,两者都链接到“Department”表的ID。
  3. 一个部门(父级)可以拥有多个子部门(子级),而那些子部门可以拥有自己的子部门(子级) SubDepartment(child)不能是其任何主要部门的父级。 “idEmployee”在表“Department_Employees”(员工只能属于一个部门)中是不同的。这些规则涵盖在前端。

    我必须计算在某些部门及其所有子部门中有多少员工(“idEmployee”)。我还要计算某些部门包括所有孩子的子部门的数量。

    让我们说我有这样的事情:

     1. MainDepartment(6 employees)
    
    
    
     - ITSector(3 employees)
    
        * Databases(4 employees)
        * Programmers(2 employees)
    
    
     - DeliverySector(4 employees)
    

    我需要输出为MainDepartment有4个子部门和19名员工。

    是否可以或建议在带有子查询的一个查询中执行此操作?我假设我需要某种递归,但我不知道如何写它。

2 个答案:

答案 0 :(得分:0)

您可以使用嵌套集模型来存储分层数据。这意味着您的表格将是以下形式: Department(ID,name, parentID, left, right ) and Department_Employees(idEmployee, idDepartment)

    SELECT COUNT(parent.name), COUNT(employee.id)
FROM Department AS node ,
     Department AS parent,
     Department_employee AS employee
WHERE node.lft BETWEEN parent.lft AND parent.rgt
        AND node.idDepartment = product.idDepartment
        AND parent.name = 'MAIN DEPARTMENT';

More on Nested set representation for hierarchical data

其他选项是保持数据库结构相同。您可以使用sub queriesstored procedure查找子部门。

select count(id), count(distinct(idDepartment)) from Department_employee 
                   where idDepartment IN ( Getsubdepartment('Department') );

答案 1 :(得分:0)

递归的声音如下:

WITH RECURSIVE dep (main_id,child_id,name) as
(SELECT d.id,d.id,d.name 
 FROM department d
 UNION ALL
 SELECT d.main_id, sd.child, d.name || '.' || sd.name
 FROM dep d INNER JOIN subdepartment sd on d.child_id=sd.parentid
)
SELECT s.name,count(idemployee) 
FROM dep d INNER JOIN dep s ON d.name LIKE s.name || '%'
LEFT JOIN department_employees de ON d.child_id=de.iddepartment
GROUP BY s.name
ORDER BY s.name;

在postgres上测试它也应该在mysql中工作。

它使用存储树的路径系统。这非常好,很容易。左右不适用于大和dinamic树非常好,因为在每个insrt你必须更新半db。如果你制作一个分支的复制粘贴,你将更新数百万条记录。