具有空值的SQL自连接问题

具有空值的SQL自连接问题,sql,join,Sql,Join,让我们以Employee表的经典自连接示例为例,其中有列empId、managerId、empName、Managername。我试图看到每个作为经理的员工都是这样,然后在表名中将经理的名字与另一个名字连接起来。现在我遇到的问题是,对于某些记录,管理器id可能为空。在这些情况下,sql不起作用,因为对于mgrId为null的行,mgr.name为null: SELECT emp.Name, mgr.Name FROM Employee e LEFT JOIN Employee mgr ON e.

让我们以Employee表的经典自连接示例为例,其中有列empId、managerId、empName、Managername。我试图看到每个作为经理的员工都是这样,然后在表名中将经理的名字与另一个名字连接起来。现在我遇到的问题是,对于某些记录,管理器id可能为空。在这些情况下,sql不起作用,因为对于mgrId为null的行,mgr.name为null:

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  

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

一旦您引入了左连接,您通常也希望使用左连接跟踪所有后续连接。链中的单个内部联接也会将之前的所有内容缩减为内部联接

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

把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 

首先,你没有加入的背景词吗?不应该

         ON e.empId = mgr.mgrId 

即使您的工作正常,名为mgr的表也应该保存带有mgr.empId和mgr.name的记录,这样就很清楚了

第二,我不喜欢在名字上加入。您应该将其转换为ID。有人结婚了,你知道的下一件事就是你有一群孤儿。。。。我怀疑这张桌子不是真的需要

第三,结果集中的两列具有相同的名称这一事实可能会导致以后出现问题——如果没有其他问题,那就是糟糕的做法

这是我将使用的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

在您的大SQL中,emp.empId=mgr.empId上的LEFT JOIN Employee mgr看起来不正确。在emp.mgrId=mgr.empIdJOIN地址在mgr.houseNo=Address.houseNo上不应该是左连接emp.mgrId=mgr.empIdJOIN地址在没有mgr行时应该是左连接。
SELECT *
FROM Employee e
LEFT JOIN Name nm 
ON nm.name = e.Name
WHERE nm.name is null