计算层次结构
Counting the hierarchy
我有一个 table 层次结构:
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_id
是 NULL
)及其下属人数(包括所有级别)
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;
得到了层数,但是如何得到层数?
首先你可以得到manager下的员工,top level manager。以后可以统计top level manager下的员工
;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
您的原始代码的问题是您忘记了“最高管理者”。但是,您可以将其保留在 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
我有一个 table 层次结构:
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_id
是 NULL
)及其下属人数(包括所有级别)
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;
得到了层数,但是如何得到层数?
首先你可以得到manager下的员工,top level manager。以后可以统计top level manager下的员工
;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 |
您的原始代码的问题是您忘记了“最高管理者”。但是,您可以将其保留在 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