取出那些没有分配到它的员工的部门

Posted

技术标签:

【中文标题】取出那些没有分配到它的员工的部门【英文标题】:To take out those dept who has no employees assigned to it 【发布时间】:2010-12-28 11:38:38 【问题描述】:

我想写一个 sql 查询,想从 EMP 表中没有分配员工的 DEPT 表中获取部门名称。

表结构:

EMP
EMPNO   ENAME    DEPTNO

DEPT
DEPTNO   DNAME

所以我想认识那些没有员工协会的部门。

【问题讨论】:

您可以使用左连接并检查 NULL,也可以使用子查询 【参考方案1】:

只有正确不存在

SELECT D.DNAME
FROM DEPT D
WHERE
 NOT EXISTS (SELECT * FROM EMP E WHERE D.DEPTNO = E.DEPTNO)

或EXCEPT,在这种情况下更复杂

SELECT D.DNAME
FROM DEPT D
EXCEPT
SELECT D.DNAME
FROM DEPT D
JOIN 
EMP E WHERE D.DEPTNO = E.DEPTNO

两者都应该给出相同的计划(使用左反半连接)

关于其他答案的注释:

LEFT JOIN 将为每位员工提供一行。你需要 DISTINCT。与 NOT EXISTS 相比,这会影响计划

如果有没有部门的员工,NOT IN 将给出错误结果。列表中带有 NULL 的 NOT IN 失败

所以一般应该使用 NOT EXISTS 或 EXCEPT

【讨论】:

您能否添加有关您尝试了哪些 dbms 的信息?在 Oracle 上,第一个查询将生成反连接(哈希或 nl 取决于数据分布),而第二个查询导致两种排序。 @Ronnis:SQL 服务器。根据经验和这个***.com/questions/4249891/…【参考方案2】:
select dname from dept where deptno not in (select deptno from emp)

【讨论】:

希望每个员工都有一个部门。 CEO 可能没有部门,deptno 可能为 NULL = 失败...【参考方案3】:
SELECT D.DNAME
FROM DEPT D
LEFT JOIN EMP E ON D.DEPTNO = E.DEPTNO
WHERE E.DEPTNO IS NULL

更新:

@bernd_k 指出 DISTINCT 在这种情况下是不必要的 (SELECT DISTINCT D.DNAME ...) - 即使没有它,也不会出现重复的部门返回。

【讨论】:

@bernd_k:你会得到每个 EMP 一行。所以你需要 DISTINCT。这是在快速更新后添加的,因此不会显示为编辑... @gbn 但那些被 where 子句排除的。对于未加入的部门,我没有重复。不需要 DISTINCT @bernd_k:这实际上是一个特例。一般来说,你通常需要 DISTINCT 来补偿由 JOIN 引起的多行。 @gbn 在这些情况下,当我只从左表中选择列时,我更喜欢 where in ... 构造,以避免 DISTINCT @gbn 承认,但要避免不同的情况是 where x in (select y ...) 情况,这是可靠的。子选择中可能的空值无关紧要。【参考方案4】:
SELECT D.DEPTNO
FROM EMP E
JOIN DEPT D ON D.DEPTNO = E.DEPTNO (+)
WHERE E.EMPNO IS NULL;

【讨论】:

【参考方案5】:

你可以从dept表中选择emp表中没有编号的部门:

SELECT dname
FROM dept 
WHERE deptno 
NOT IN (SELECT DISTINCT deptno 
FROM emp);

【讨论】:

请更新并简要说明您的代码的作用) @junkfoodjunkie【参考方案6】:
Select DName 
from DEPT
where DName NOT IN (Select Distinct EMP.DName from EMP);

【讨论】:

"In" 子句的限制因数据库而异。【参考方案7】:
select  x.DEPTNO from dept x where x.DEPTNO not in 
(select d.DEPTNO from department d join
employee e where e.deptid=d.DEPTNO)

子查询用于获取与某个部门关联的所有员工:

select d.DEPTNO from department d join
employee e where e.deptid=d.DEPTNO
 and using select  x.DEPTNO from dept x where x.DEPTNO 

not in 会给不属于任何部门的员工。

【讨论】:

感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。【参考方案8】:
SELECT ID,NAME,SAL,DEPTNAME,DEPTID
FROM emp
FULL JOIN
DEPT
ON EMP.departmentid=DEPT.DEPTID
WHERE DEPTID IS NULL

【讨论】:

请提供更详细的答案,而不仅仅是一段代码。【参考方案9】:

下面没有使用任何 except 或 not in 并且在性能方面它更好

select d.dname 
from emp e right
join dept d on e.deptno=d.deptno
group by d.dname
having count(e.empno)=0

【讨论】:

以上是关于取出那些没有分配到它的员工的部门的主要内容,如果未能解决你的问题,请参考以下文章

4查找所有已经分配部门的员工

sql 查找所有已经分配部门的员工

26汇总各个部门当前员工的title类型的分配数目

牛客网SQL-第4题-请你查找所有已经分配部门的员工的last_name和first_name以及dept_no,未分配的部门的员工不显示

57使用含有关键字exists查找未分配具体部门的员工的所有信息

Java实例——为新员工分配部门