MS SQL中UKStaffList表员工与经理关联查询方法求助
抱歉提出如此基础的问题,我在工作中借助StackOverflow通常能顺利编写SQL查询,但这次遇到了难题。我有一个MS SQL表
[UKStaffList],数据如下:
EmployeeID FirstName LastName ManagedBy 1001 Robert Anderson 1004 1002 Chris Thompson 1004 1003 Mary Wright 1004 1004 Andrew Denton 1005 1005 Susan Rogers 1005 1006 Michael Stevens 1007 1007 Alice Lee 1005 1008 John Clarke 1007 我希望创建一个视图,在原有数据基础上增加经理姓名列,期望结果如下:
EmployeeID FirstName LastName ManagedBy Manager 1001 Robert Anderson 1004 Andrew Denton 1002 Chris Thompson 1004 Andrew Denton 1003 Mary Wright 1004 Andrew Denton 1004 Andrew Denton 1005 Susan Rogers 1005 Susan Rogers 1005 Susan Rogers 1006 Michael Stevens 1007 Alice Lee 1007 Alice Lee 1005 Susan Rogers 1008 John Clarke 1007 Alice Lee 我尝试了以下查询:
SELECT EmployeeID, FirstName, LastName, ManagedBy, CASE WHEN ManagedByID = EmployeeID THEN CONCAT(FirstName, ' ', LastName) ELSE 'N/A' END AS Manager FROM UKStaffList但该查询仅在第5行(Susan Rogers自管理)显示正确经理姓名,其余行均为N/A。可见此查询仅匹配同行的ManagedBy与EmployeeID。
我需要编写查询,将ManagedBy对应的EmployeeID的姓名拼接为Manager列,且数据保留在原表中。我猜测可能需要嵌套查询,但不知如何入手,恳请指出问题并提供指导。
你的思路方向是对的,但问题在于你没有把员工表和它自己关联起来——你现在的查询只是在当前行里找匹配,而经理的信息其实是表中另一行(或者自管理时的同一行)的数据。这里需要用**自连接(Self Join)**来解决,也就是把表当作两个独立的表来关联:一个是员工表,一个是经理表。
正确的SQL查询
CREATE VIEW UKStaffWithManager AS SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagedBy, CONCAT(m.FirstName, ' ', m.LastName) AS Manager FROM UKStaffList e INNER JOIN UKStaffList m ON e.ManagedBy = m.EmployeeID;
代码解释
- 表别名:给
UKStaffList起了两个别名e(代表employee,员工)和m(代表manager,经理),这样就能区分开员工数据和对应的经理数据。 - 关联条件:
ON e.ManagedBy = m.EmployeeID——把员工的ManagedBy字段和经理的EmployeeID字段关联起来,这样就能找到每个员工对应的经理记录。 - 拼接姓名:用
CONCAT(m.FirstName, ' ', m.LastName)把经理的名和姓拼接成完整的经理姓名,正好符合你想要的格式。 - 自管理的情况:像Susan Rogers(EmployeeID=1005)的
ManagedBy是自己的ID,自连接时会匹配到她自己的记录,所以自动会显示她自己的姓名,不需要额外的CASE判断。
为什么你的原查询不对?
你的原查询里用了CASE WHEN ManagedByID = EmployeeID(这里应该是笔误,原表字段是ManagedBy不是ManagedByID),但这个判断只在当前行的ManagedBy等于当前员工ID时才生效,而其他员工的经理都是另一个ID,自然匹配不到,所以显示N/A。自连接才是正确的方式,因为它能跨行找到对应的经理数据。
如果担心有员工的ManagedBy不存在对应的EmployeeID(比如数据错误),可以把INNER JOIN改成LEFT JOIN,然后用ISNULL处理空值:
CREATE VIEW UKStaffWithManager AS SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagedBy, ISNULL(CONCAT(m.FirstName, ' ', m.LastName), 'Unknown') AS Manager FROM UKStaffList e LEFT JOIN UKStaffList m ON e.ManagedBy = m.EmployeeID;
这样如果某个员工的经理ID在表中找不到,会显示Unknown而不是NULL。
内容的提问来源于stack exchange,提问作者Stampers

