将经理更改为员工,使用 not in 子句,使用联合命令时有些小混乱

Posted

技术标签:

【中文标题】将经理更改为员工,使用 not in 子句,使用联合命令时有些小混乱【英文标题】:changing manager to employee, using not in clause, some minor confusing in using joint commands 【发布时间】:2015-11-28 06:06:41 【问题描述】:

我的架构如下:

EMPLOYEE (fmane, minit, lname, ssn, birthdate, address, sex, salary, superssn, dno), KEY: ssn
DEPARTMENT (dname, dnumber, mgrssn, mgrstartdate), KEY: dnumber.
PROJECT  (pname, pnumber, plocation, dnum), KEY: pnumber.
WORKS_ON (essn, pno, hours), KEY: (essn, pno)
DEPENDENT  (essn, dependent-name, sex, bdate, relationship), KEY: (essn, dependent-name)

我想查找那些不参与位于芝加哥的任何项目的经理的姓氏和 SSN。

注意:我把原来的问题修改为练习SQL,所以我把经理改成了员工

这是我目前所拥有的:

  select e.lname
  from Employee e
  where e.ssn not in 
       (select w.essn
        from works_on w, Project p
        where w.pno = p.pnumber
        and p.plocation = 'Cleveland')

所以基本上我的修改正确吗?还有

    我需要写 e.lname 还是只写 lname,因为人们告诉我如果只有一个项目我可以简单地使用 lname?

    使用 NOT IN 子句时最令人困惑的部分,我如何知道何时应该使用 e.ssn 或 ssn?

谢谢

【问题讨论】:

【参考方案1】:

使用not in (...) 可以说是最容易阅读/理解的,但通常表现最差。

表现最好的通常是对错过的连接进行外连接过滤:

select ssn, lname
from Employee e
left join (
    select essn
    from Project p
    join works_on w on pno = pnumber
    where plocation = 'Cleveland') x on essn = ssn
where essn is null

这给出了相同的结果:

select ssn, lname
from Employee e
where ssn not in (
    select essn
    from Project p
    join works_on w on pno = pnumber
    where plocation = 'Cleveland')

请注意,在这两种方法中,子查询如何首先从 Project 中进行选择,然后使用 where 子句选择 Cleveland 位置,这为优化器提供了在位置上使用索引(如果存在)的最佳机会,并且/或者做最少的工作来获得在其中工作的员工(通过pno 上的索引,如果存在的话)。

还要注意正确连接的使用(其语法在 20 多年前成为 SQL 标准的一部分)。


关于限定列名与它们来自的表名或别名 - 如果列是明确的,则它是可选的,但通常在生产代码中限定是一种好习惯,因为:

您无需查阅方案即可确定列的位置(自我记录) 如果架构发生变化,使列不再明确,您的查询可能会突然中断,您可能不知道原因

【讨论】:

你能用not in为我写一个答案吗?我保证我会接受它 谢谢 e.lname 或 lname 都可以吗? @lin(注意进一步的编辑)是的,只要lname 就可以了,因为在从中选择的表中只有一个这样的列 赞你!最后还有为什么必须使用work_on,因为我只需要find location,它不在work_on中 部分来自works_on w, Project p where w.pno = p.pnumber

以上是关于将经理更改为员工,使用 not in 子句,使用联合命令时有些小混乱的主要内容,如果未能解决你的问题,请参考以下文章

SQL IN 工作但 NOT IN 不起作用

在 Postgres 中使用 NOT IN 子句时的困惑

数据过滤

如何使用 NOT IN 子句添加超过 1000 个值

MySQL:在 WHERE 子句中带有 NOT IN 的从属子查询非常慢

使用 NOT IN 子句替代 Hive 查询