2017-04-15 103 views
0

SELECT e.ManagerID, count(*) as NumberOfDepartments From HumanResources.Employee e, Person.Contact c where e.ContactID = c.ContactID group by e.ManagerID;无法弄清楚如何连接表

的目标是写一个报告,以显示经理和他们独特的监督不同的部门数量的经理ID,名字和姓氏。只显示监督大多数部门的经理。 我必须确保所有员工都在雇用(即enddate不包含日期)。 上面的代码正在显示编号managerid和他运行的部门数量,但每当我尝试把名字和姓氏放在我不得不把他们也放在'group by'子句,这样,它使整个报告变得疯狂。请帮忙。
Database Here

+1

(一)如何你能认识一个经理吗? –

+0

(b)经理必须当前被占用,您没有在查询中添加此项。 –

+0

如果managerID中有值,则表示他/她是经理 – Obi

回答

1

从您的模式,似乎在EmployeemanagerID列都将填充经理对于员工的ID。这可以解释为什么当添加firstNamelastName时,报告变得很疯狂,因为您将按员工姓名而非经理人进行分组。

没有看到表格内容很难说,但你可能会认为不是managerID填充。

如果是这样的话,你可以写这样的查询

select e.EmployeeID, c.firstName, e.lastName, count(distinct edh.DepartmentID) 
from Employee e 
join Contact c 
on  e.ContactID = c.ContactID 
join Employee e2 
on  e1.EmployeeID = e2.ManagerID 
join EmployeeDepartmentHistory edh 
on  e2.EmployeeID = edh.EmployeeID 
where e.ManagerID is null and edh.EndDate is null 
group by e.EmployeeID, c.firstName, e.lastName 

Employee表的第一个实例是管理者(因为你设置where e.ManagerID is null),连接与Contact让你的经理的名字,Employee的第二个实例可让您获得由每位经理管理的所有人员,并且加入EmployeeDepartmentHistory可让您获得他们的部门(您指望)和他们的EndDate,这必须是null以确保他们目前处于就业状态。

编辑

请注意我写的连接方式;把它们写成你的from子句中的逗号分隔表名,中的连接条件是a bad habit that should be kicked,因为它使得阅读,维护和更改它们更加困难。这就是为什么join在SQL语言于1992年

+0

伟大的工作和解释,斯特凡诺。但我不明白员工和联系人之间的一对多关系;他们不应该分享一个关键? –

+0

关于'JOIN',如果它们是在1992年推出的,那么SQL花费了太多时间来采用它,它从一开始就在关系代数中(我认为)。然而,我认为我们夸大了“踢坏习惯的坏习惯”:'select * from a,b'是一个'CROSS JOIN',尽管我自己从来没有使用它(除非在极少数情况下我需要笛卡尔积),它仍然是一个完全合法的SQL构造。 –

+0

@GiorgosAltanis关于连接,我编辑我的答案是更准确,因为你显然是正确的,'join'一直存在于关系代数中,而且“踢坏的习惯”主要应用于'inner join',多少到'交叉连接'。谢谢:) –

1

引回在MSSQL:

SELECT e.ManagerID, e.FirstName, e.LastName, COUNT(*) AS NumberOfDepartments FROM HumanResources.Employee e 
INNER JOIN Person.Contact c ON e.ContactID=c.ContactID 
GROUP BY e.ManagerID, e.FirstName, e.LastName 

如果您需要在MySQL中,变化到模式和INNER JOIN加盟