员工可以在多个部门工作,每个部门可以有很多员工。因此需要一个关系表
TABLES:
EMP(EID,为ename,EAGE,esalary)
作品(EID,确实,pct_time)
部门(确实,dname,预算,经理)
查找所有在软件和硬件中工作的员工:
SELECT e.ename FROM EMP e, Works w, Dept d
WHERE e.eid = w.eid AND w.did = d.did AND d.did =
(SELECT did FROM dept WHERE dname = 'Hardware' OR 'Software')
作为Per Jon:
SELECT e.ename FROM EMP e OR Works w OR Dept d
WHERE e.eid = w.eid AND w.did = d.did AND d.did =
(SELECT did FROM dept WHERE dname = 'Hardware' OR 'Software')
我无法弄清楚如何确保在同一个eid下的硬件和软件的Works中有两个条目。
答案 0 :(得分:1)
select e.name
from emp e, works h_w, dept h_d, works s_w, dept s_d
where e.eid = h_w.eid
and e.eid = s_w.eid
and h_w.did = h_d.did
and h_d.dname = 'Hardware'
and s_w.did = s_d.did
and s_d.dname = 'Software'
答案 1 :(得分:1)
以下是如何解决问题的步骤:
works
表格中的所有行所以我们首先要做的是从works
表中选择,将其加入dept
表,并过滤掉任何非硬件或软件的部门:
SELECT a.*
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
然后我们想要做的是按每个员工分组,这将使我们能够访问聚合信息,例如每个员工的行数,或者总和/最大/最小/平均/等。其他专栏。我们必须使用计数:
SELECT a.eid
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
GROUP BY a.eid
HAVING COUNT(1) = 2
这只给我们提供了恰好有两行的eid
(即适用于软件和硬件部门)。
但eids
还不够。我们需要有关员工的全部信息,因此我们必须将整个查询包装起来并将其加入employees表以获取其余信息:
SELECT a.*
FROM emp a
INNER JOIN
(
SELECT a.eid
FROM works a
INNER JOIN dept b ON a.did = b.did
WHERE b.dname IN ('Hardware','Software')
GROUP BY a.eid
HAVING COUNT(1) = 2
) b ON a.eid = b.eid
你有它:在软件和硬件部门工作的员工。您可以单独执行上面的每个查询,以查看我们如何达到最终解决方案的中间步骤。
答案 2 :(得分:1)
以下是查询的另一种表述:
SELECT e.*
FROM emp AS e
JOIN (SELECT w.eid
FROM works AS w JOIN dept AS d
ON d.did = w.did AND d.dname = 'Software') AS s
ON s.eid = e.eid
JOIN (SELECT w.eid
FROM works AS w JOIN dept AS d
ON d.did = w.did AND d.dname = 'Hardware') AS h
ON h.eid = e.eid
这有两个对称子查询,一个生成软件部门的员工ID,一个生成硬件部门的员工ID。选定的员工是那些ID在两个部门中列出的员工(因为他们都是内部联接)。