【问题标题】:Counting the hierarchy计算层次结构
【发布时间】:2021-09-11 04:05:52
【问题描述】:

我有一个带有层次结构的表:

CREATE TABLE mng 
(
    id INTEGER NOT NULL PRIMARY KEY, 
    name VARCHAR(50) NOT NULL,
    manager_id INTEGER
);

INSERT INTO mng (id, name, manager_id) VALUES (1, 'Lola', NULL);
INSERT INTO mng (id, name, manager_id) VALUES (2, 'Bella', NULL);
INSERT INTO mng (id, name, manager_id) VALUES (3, 'Lo', 1);
INSERT INTO mng (id, name, manager_id) VALUES (4, 'Ann', 2);
INSERT INTO mng (id, name, manager_id) VALUES (5, 'Ki', 3);
INSERT INTO mng (id, name, manager_id) VALUES (6, 'Qo', 5);

我需要打印所有高级管理人员(manager_idNULL)及其下属人数(包括所有级别)

   id   |   cnt
--------+---------
   1    |   3
   2    |   1

更新 正在尝试这样的事情:

WITH DirectReports(ManagerID, Employee) AS   
(  
    SELECT id, 0 AS Employee  
    FROM mng 
    WHERE manager_id IS NULL  
  
    UNION ALL  
  
    SELECT e.id, Employee + 1  
    FROM mng AS e  
    INNER JOIN DirectReports AS d  
    ON e.manager_id  = d.ManagerID    
)  
SELECT ManagerID, Employee  
FROM DirectReports  
ORDER BY ManagerID;  

有等级号,但如何获得计数?

【问题讨论】:

  • 我正在使用 sqlfiddle) 但可以说它的 MS SQL Server 2017
  • 您的原始代码在 SQLFiddle 中不起作用。您创建了一个名为 Employee 的表,但所有其他代码随后都引用了 mng。同样,create table 脚本中的列名叫做 manager_id,但是 cte 使用的是 mng_id。

标签: sql sql-server hierarchy


【解决方案1】:

原始代码的问题是您忘记了“最高管理者”。但是,您可以将其保留在 CTE 中,并简单地为每位员工列出:

WITH DirectReports(id, TopMgr, ManagerID, Employee) AS   
(  
    SELECT id, id, NULL, 0 AS Employee
    FROM mng 
    WHERE manager_id  IS NULL  
  
    UNION ALL  
  
    SELECT e.id, d.TopMgr, e.manager_id, 1 AS Employee
    FROM mng AS e  
    INNER JOIN DirectReports AS d  
    ON e.manager_id  = d.id   
)  
SELECT TopMgr, SUM(Employee)
FROM DirectReports  
GROUP BY TopMgr
ORDER BY TopMgr

输出:

    TopMgr  EmployeeCount
1   3
2   1

【讨论】:

    【解决方案2】:

    首先,您可以让经理下属的员工,顶级经理。稍后,您可以计算最高级别经理下的员工。

    ;WITH DirectReports(EmployeeId, ManagerID, TopMostManagerId) AS   
    (  
        SELECT id, Null, id 
        FROM #mng 
        WHERE manager_id IS NULL  
      
        UNION ALL  
      
        SELECT e.id, e.manager_Id, d.TopMostManagerId  
        FROM #mng AS e  
        INNER JOIN DirectReports AS d  
        ON e.manager_id  = d.EmployeeId    
    )  
    SELECT TopMostManagerId, COUNT(EmployeeId) as CountOfEmployees
    FROM DirectReports 
    WHERE ManagerID is not null -- excludes toplevel manager
    group by TopMostManagerId 
    
    TopMostManagerId CountOfEmployees
    1 3
    2 1

    【讨论】:

    • @user2050247,如果它回答了你的问题,请点击勾号并将其标记为答案,以便以后对其他人有所帮助
    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多