首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有空值的SQL自连接问题

具有空值的SQL自连接问题
EN

Stack Overflow用户
提问于 2011-02-02 11:00:12
回答 3查看 4.3K关注 0票数 0

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

代码语言:javascript
运行
复制
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

有没有人能为此提供一个解决方案?

很抱歉过于简化了问题:对于每个员工行,我还想要经理行(其中mgrId是empId的行),然后将经理行的属性连接到其他表。如下所示:

代码语言:javascript
运行
复制
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  

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

EN

回答 3

Stack Overflow用户

发布于 2011-02-02 11:05:10

一旦引入了left join,您通常也想在所有后续的join后面加上LEFT。链中的一个内部连接也会将它之前的所有内容都减少为一个内部连接。

代码语言:javascript
运行
复制
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
票数 8
EN

Stack Overflow用户

发布于 2011-02-02 12:27:28

首先,你不是有join回词吗?不应该

代码语言:javascript
运行
复制
         ON e.empId = mgr.mgrId 

be

代码语言:javascript
运行
复制
         ON e.mgrId = mgr.empId

即使您的表可以正常工作,名为"mgr“的表也应该保存带有mgr.empId和mgr.name的记录,因此这一点很清楚。

其次,我不喜欢名字部分的加入。您应该将其转换为ID。(有人结婚了,下一件事你知道的是你有一群孤儿……)我怀疑这张桌子并不是真的需要。

第三,结果集中有两列具有相同的名称( name ),这一事实可能会导致以后出现问题--如果没有其他问题,这是一种不好的做法。

这是我将使用的SQL:

代码语言:javascript
运行
复制
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来查看是否有员工在Name表中没有记录,并修复它们:

代码语言:javascript
运行
复制
SELECT *
FROM Employee e
LEFT JOIN Name nm 
ON nm.name = e.Name
WHERE nm.name is null
票数 2
EN

Stack Overflow用户

发布于 2011-02-02 11:15:41

只需将ON子句移到更合适的位置即可

代码语言:javascript
运行
复制
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 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4870366

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档