SQL 查询以获取每个经理下的员工的递归计数
Posted
技术标签:
【中文标题】SQL 查询以获取每个经理下的员工的递归计数【英文标题】:SQL Query to get recursive count of employees under each manager 【发布时间】:2013-10-30 17:52:53 【问题描述】:我正在寻找一个 SQL 查询来获取每个经理或其他表中的一些经理下的 Employee
的递归计数。
表结构是:
Emp_Table
Emp_id Manager_id
1 1
2 1
3 1
4 3
5 3
6 5
7 5
8 7
9 7
10 7
执行表:
此表只是此处可用的选定经理。我需要统计这位经理下的每个员工的人数
Manager_id
1
4
7
8
我正在寻找以下输出
Manager_ID Count_of_Employees
1 9
4 0
7 3
8 0
请注意,您的回答仅提供了我收到的每位经理的直接下属员工人数。但我正在寻找经理的递归员工报告。在我上面的示例中,根据您的查询,我将获得 Manager_id 1 和员工人数为 3,但我正在寻找输出为 9。提前致谢!
感谢您的所有回复。我终于得到了查询。请找到我的答案。
【问题讨论】:
@DanAndrews.. 我不是在寻找以下查询。我清楚地说我正在寻找名单下的雇员的recruitative aunt。我错过了一些东西。只是想得到别人的帮助。但是有人标记了降级的问题。 什么? “我正在寻找一个 SQL 查询来获取 Employee 的计数......” 通常在 *** 上,人们会先发布他们尝试过的内容。从那里,人们可以提供帮助。如果你收到的答案不是你想要的,那么也许你需要看看你在问什么。 @Dhana:你可以看到每个人都对此感到困惑,首先是不清楚。 @DanAndrews.. 很抱歉给您带来麻烦。在我的示例输出中,我清楚地发布了带有递归计数的输出。谢谢! 【参考方案1】:首先,重要说明:Emp_Table
的第一行,Emp_id==Manager_Id==1
不仅没有意义,还会导致无限递归 。我建议你删除它。
然而,为了提供答案,我首先创建了一个视图来消除此类无效条目,并使用 that 而不是Emp_Table
:
create view valid_mng as
select Emp_Id,Manager_id from Emp_Table
where Emp_Id<>Manager_Id
所以它归结为以下,在递归 CTE 的帮助下:
With cte as (
select Emp_Id,Manager_id from valid_mng
union all
select c.Emp_Id,e.Manager_Id
from cte c join valid_mng e on (c.Manager_Id=e.Emp_Id)
)
select m.Manager_Id,count(e.Emp_Id) as Count_of_Employees
from [Execute] m
left join cte e on (e.Manager_Id=m.Manager_Id)
group by m.Manager_Id
如果您最终删除了有问题的行,或者最好按照 HABO 的建议设置 Manager_Id=NULL
,只需忽略 valid_mng
视图并将其替换为各处的 Emp_Table
。 p>
另外附注:Execute
是 MSSQL 中的保留字。避免在用户对象命名中使用保留字始终是一个好习惯。
【讨论】:
@Dhana - 通常将经理置于由 NULL 的Manager_Id
表示的层次结构(或食物链)的顶部。它可以避免卡在管理自己的经理身上。
@geomagas.. 这对我有用。谢谢!
@geomagas.. 你的答案执行时间太长了。我修改了一些东西来更改代码以使其完美运行。我为我的问题提交了最佳答案。请看一看。无论如何,非常感谢您的工作。
@Dhana:我在你的问题中没有看到任何性能要求。
@geomagas .. 干得好。我接受你的回答是好的。实时我有十万行。如果可以的话,你能帮我提高这个查询的性能吗?【参考方案2】:
类似于geomagas,但不是从中派生出来的。它递归地构建管理报告树,然后对其进行汇总。
declare @Emp_Table as Table ( Emp_id Int Identity, Manager_id Int );
insert into @Emp_Table ( Manager_id ) values
( 1 ), ( 1 ), ( 1 ), ( 3 ), ( 3 ), ( 5 ), ( 5 ), ( 7 ), ( 7 ), ( 7 );
select * from @Emp_Table;
declare @Execute as Table ( Manager_id Int );
insert into @Execute ( Manager_id ) values
( 1 ), ( 4 ), ( 7 ), ( 8 );
select * from @Execute;
with Reports as (
select Manager_id, Emp_id, Manager_id as Top_Manager_id
from @Emp_Table where Manager_id <> Emp_id
union all
select ET.Manager_id, ET.Emp_id, R.Top_Manager_id
from Reports as R inner join
@Emp_Table as ET on ET.Manager_id = R.Emp_id
)
select E.Manager_id, Count( R.Emp_id ) as Count_Of_Employees
from @Execute as E left outer join
Reports as R on R.Top_Manager_id = E.Manager_id
group by E.Manager_id;
【讨论】:
【参考方案3】:您可以使用分组方式:
SELECT count(*) AS Count_of_Employees,
Manager_ID
FROM yourtable
GROUP BY Manager_ID
【讨论】:
@Sadek.. 谢谢!您的答案仅给出了我得到的每位经理的直接下属员工人数。布特我正在寻找与经理一起重复的员工报告。在我上面的示例中,根据您的查询,我将得到 Manager_id 1 计数为 3,但我正在寻找输出为 9。感谢是 Advance!【参考方案4】:我遇到了这样的问题,查找属于最高经理的员工人数
表:
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name VARCHAR(255) NOT NULL,
managerId INTEGER,
FOREIGN KEY (managerId) REFERENCES employees(id)
);
INSERT INTO employees(id, name, managerId) VALUES(1, 'Rob', null);
INSERT INTO employees(id, name, managerId) VALUES(2, 'Tom', null);
INSERT INTO employees(id, name, managerId) VALUES(3, 'Roger', 1);
INSERT INTO employees(id, name, managerId) VALUES(4, 'Victor', 3);
INSERT INTO employees(id, name, managerId) VALUES(5, 'John', 4);
INSERT INTO employees(id, name, managerId) VALUES(6, 'Shawn', 2);
-- Expected output
-- Id EmployeeCount
-- --------------------
-- 1 3
-- 2 1
我的解决方案是:
WITH EmployeeCTE
AS (SELECT e.id, e.managerid as topmanager
FROM employees e, employees m
WHERE e.managerid = m.id AND m.managerid IS NULL
UNION ALL
SELECT e.id, mgr.topmanager
FROM employees e, EmployeeCTE mgr
WHERE e.managerid = mgr.id)
SELECT topmanager, count(*)
FROM EmployeeCTE AS u
GROUP BY topmanager;
【讨论】:
【参考方案5】:SELECT Manager_id, COUNT(Emp_id) AS Count_of_Employees
FROM Emp_Table
WHERE Manager_id IN (1,4,7,8)
GROUP BY Manager_id
【讨论】:
谢谢@marc_s,你能告诉我你是如何格式化的吗?每次我尝试给出 SQL 格式时,结果都不正确。 如果您发布代码、XML 或数据示例,只需在文本编辑器中突出显示这些行,然后单击编辑器工具栏上的“代码示例”按钮 (
)(左起第三个,第二组图标)以很好地格式化和语法突出显示它。或突出显示行并按 Ctrl-K 进行格式化。
再次感谢@marc_s!
另外,你可能想要使用这个(如果你买不起 RedGate 的工具)architectshack.com/PoorMansTSqlFormatter.ashx【参考方案6】:
您可能想尝试以下方法:
SELECT MANAGER_ID,
COUNT(EMP_ID) AS EMP_COUNT
FROM EMP_TABLE
GROUP BY MANAGER_ID
【讨论】:
【参考方案7】:SELECT manager_id,
count(DISTINCT emp_id)
FROM emp_table
GROUP BY manager_id
UNION
SELECT manager_id,
0
FROM execute_table
WHERE manager_id NOT IN (
SELECT manager_id
FROM emp_table
)
【讨论】:
【参考方案8】:SELECT COUNT(Emp_id) county,
Manager_id
FROM Emp_Table
GROUP BY Manager_id
【讨论】:
【参考方案9】:SELECT Manager_Id,
Count(Employee_Id)
FROM Emp_Table
WHERE Manager_Id IN (
SELECT Manager_Id
FROM Manager
)
GROUP BY Manager_Id
【讨论】:
【参考方案10】:这是一个简单的 pl sql 查询,用于获取经理下的员工总数(直接和间接)。
select empno , ename,
(
select count(empno) from emp
start with ename = a.ename
connect by prior empno = mgr
) as under
from emp a;
【讨论】:
以上是关于SQL 查询以获取每个经理下的员工的递归计数的主要内容,如果未能解决你的问题,请参考以下文章