如何在SQL中解决此查询?

时间:2015-04-08 19:20:07

标签: sql

我有以下两种关系:

  • EMP( ENO ,ENAME,JOB,DATEJOB,SAL,DNO)
  • DEPT( DNO ,DNAME,DIR)

EMP是员工与他们的号码ENO,他们的姓名ENAME,他们的职位名称JOB,他们被雇用的日期,他们的工资SAL以及他们在DNO工作的部门号码的关系(参考DNO的forgein密钥)在DEPT)。

DEPT是部门与每个部门DNO的数量,部门DNAME的名称,部门DIR的主管(引用ENO的forgein密钥)的关系。

我的问题是:

  • 在SQL中编写以下查询。

查找具有相同工作和相同导演的员工的姓名,以及#Joe;#'

我的尝试是:

SELECT ENAME 
FROM   EMP, DEPT
WHERE  EMP.DNO = DEPT.DNO
AND    (DIR, JOB) IN (
                      SELECT DIR, JOB
                      FROM   EMP, DEPT
                      WHERE  ENAME = 'Joe'
                      AND    EMP.DEPT = DEPT.DNO
                      )
AND  ENO NOT IN (
                 SELECT ENO
                 FROM   EMP, DEPT
                 WHERE  ENAME = 'Joe'
                 AND    EMP.DEPT = DEPT.DNO
                )

我找到了这个问题的解决方案,但我无法达成一致。

这是我发现的:

SELECT ENAME
FROM   EMP, DEPT
WHERE  ENAME <> 'Joe'
AND    EMP.DNO = DEPT.DNO
AND    (DIR, JOB) = (
                     SELECT DIR, JOB
                     FROM   EMP, DEPT
                     WHERE  ENAME = 'Joe'
                     AND    EMP.DEPT = DEPT.DNO
                     )

问题是,我们不得不考虑乔&#39;在结果中。但是乔&#39;哪个?

3 个答案:

答案 0 :(得分:1)

你说的第二个解决方案是错误的。如果有两个'乔'它将无法正常工作。这就是为什么你应该根据唯一的ENO而不是非唯一的名称进行排除。第一个查询不会出于同样的原因。为了确定,您不能仅通过名称或标题或部门进行选择,因为这些可能是重复的。我们部门有三位Chris程序员。

此外,该连接语法已过时,因为在某些情况下它可能会导致数据库混淆。有关当前语法的说明,请参阅http://www.w3schools.com/sql/sql_join_inner.asp

答案 1 :(得分:1)

您正在使用的逗号加入方式已经过时了很长时间。我认为以下就是你所追求的。我们的想法是为自己加入一张桌子。这是通过在此处提供表别名 - sourcetwin来完成的。

SELECT twin.ENAME
FROM EMP AS source
JOIN EMP AS twin ON twin.DNO = source.DNO AND twin.JOB = source.JOB
WHERE source.ENAME = 'Joe' AND source.ENO <> target.ENO

答案 2 :(得分:1)

看起来“导演”有可能领导多个部门。至少,信息模型似乎没有任何限制(即DIR没有唯一约束)

据推测,我们通过查找EMPENAME属性等于'Joe'的元组来识别员工'Joe'。

大概,我们会通过从DIR关系中获取DEPT属性的值来识别Joe的“导演”。

如果我们希望员工与Joe处于“同一部门”,我们可以使用DNO属性的值,...但是要求说“相同的导演”。所以,如果同一位导演负责多个部门,我们将会让所有部门由该主管领导。

然后,这是一个简单的问题,让所有员工都进入这些部门,并检查与乔的“工作”相匹配的“工作”。

SELECT e.ENAME
  FROM EMP j
  JOIN DEPT i
    ON i.DNO = j.DNO
  JOIN DEPT d
    ON d.DIR = i.DIR
  JOIN EMP e
    ON e.DNO = d.DNO
   AND e.JOB = j.JOB
 WHERE j.ENAME = 'Joe'

同样,如果我们只想要与Joe在“同一部门”中的员工,我们可以免除其中一个对DEPT的引用。如果Joe的主管负责另一个部门,那么结果会有所不同,并且其他部门的员工也有相同的工作......该员工将被排除在此查询之外:

 SELECT e.ENAME
   FROM EMP j
   JOIN DEPT i
     ON i.DNO = j.DNO
-- JOIN DEPT d
--    ON d.DIR = i.DIR
  JOIN EMP e
--  ON e.DNO = d.DNO
    ON e.DNO = i.DNO
   AND e.JOB = j.JOB
 WHERE j.ENAME = 'Joe'

如果需要从结果集中排除Joe,那么我们可以在WHERE子句中添加另一个谓词。如果我们不假设ENAME不能有NULL值......

   AND ( e.ENAME IS NULL OR e.ENAME <> 'Joe')