2011-02-02 83 views
0

让我们的经典自连接例如Employee表中,我们有列empId,managerId,empName,Managername。我想看到,谁是经理,然后在表名称另一名加盟经理的名字每一个员工。现在,我有问题的部分是,经理ID可以是空的一些记录。在这些情况下,SQL不起作用,因为mgr.name是空的,其有MGRID为空行:SQL自联接与空值的问题

SELECT emp.Name, mgr.Name FROM Employee e 
LEFT JOIN Employee mgr ON e.empId=mgr.mgrId 
JOIN Name nm ON nm.name = mgr.Name 

是否有人可以提供一个解决方案?

对不起,这个问题过于简单: 它更像每个员工行,我也想要mgr行(mgrId是empId的行),然后将mgr行的属性连接到其他表。类似这样的:

select 
    emp.empId,mgr.empId,dept.deptName 
from Employee emp 
JOIN Address addr on 
    emp.houseNo = addr.houseNo 
JOIN dept dept on 
    dept.deptAddress = addr.deptAddress 
LEFT JOIN Employee mgr on 
    emp.empId = mgr.empId 
JOIN Address address on 
    mgr.houseNo = address.houseNo 
JOIN dept department on 
    department.houseNo=address.deptAddress 
where 
    department.deptId=dept.deptId 

使用所有左连接对此不起作用。谢谢您的帮助。

+0

在你大SQL这样的:LEFT JOIN员工经理在emp.empId = mgr.empId看起来不正确。不应该是LEFT JOIN Employee mgr on emp.mgrId = mgr.empId – JBrooks 2011-02-02 04:38:42

回答

8

一旦你引入了一个左连接,你通常也想跟随所有后续的连接。一个单一的INNER JOIN在链中减少一切之前它为内连接为好。

SELECT 
    emp.Name, mgr.Name 
FROM Employee e 
LEFT JOIN Employee mgr ON 
    e.empId = mgr.mgrId 
LEFT JOIN Name nm ON 
    nm.name = mgr.Name 
0

只需推动ON子句就在哪里更合适

SELECT emp.Name, mgr.Name 
FROM Employee e 
    LEFT JOIN Employee mgr 
     JOIN Name nm 
     ON nm.name = mgr.Name 
    ON e.empId=mgr.mgrId 
2

首先,不要你有backwords的加入?不应

  ON e.empId = mgr.mgrId 

  ON e.mgrId = mgr.empId 

即使你的作品命名表“经理”应与mgr.empId记录和mgr.name所以很清楚。

其次,我不喜欢加入名称部分。您应该将其转换为ID。 (有人结婚,你知道接下来的事情你有一堆孤儿......)我怀疑是不是真的需要这个表。第三,结果集中的2列具有相同名称(名称)的事实可能会导致后续问题 - 如果没有其他问题,则会导致问题。

这是SQL我会用:

SELECT emp.Name, '(none)' AS Manager 
FROM Employee emp 
WHERE NOT EXISTS (SELECT 1 
    FROM Employee mgr 
    WHERE mgr.empId = emp.mgrId) 

UNION ALL 

SELECT emp.Name, mgr.Name AS Manager 
FROM Employee emp 
JOIN Employee mgr ON emp.mgrId=mgr.empId 
JOIN Name nm ON nm.name = mgr.Name 
ORDER BY 1, 2 

不要担心,如果这看起来效率不高,现代SQL编译器在大多数情况下,同样的事情,无论你如何写它结束了。

但首先,我要运行这个SQL,看看我有没有记录在名称表和解决这些问题的任何员工:

SELECT * 
FROM Employee e 
LEFT JOIN Name nm 
ON nm.name = e.Name 
WHERE nm.name is null