2

考虑两个表。Employee 和 Project.Employee 表具有 eid、ename 等字段。Project 表具有 pid、pname 等字段。现在,由于一个员工可以从事许多项目,一个项目可以由许多员工完成,因此,很明显,两个表之间存在多对多关系。打破多对多,并创建一个名为Assignment的新表,其中包括作为外键的eid和pid。

这是问题,我想找出那些在多个项目中合作过的员工对。例如,如果 emp A 和 emp B 在多个项目上合作过,那么他们有资格进行上述查询结果。

请让我知道上述问题的查询是什么。

4

3 回答 3

8

这是一个非常常见且直接的解决方案:

SELECT a1.eid, a2.eid
FROM Assignment a1
JOIN Assignment a2 ON (a1.eid < a2.eid AND a1.pid = a2.pid)
GROUP BY a1.eid, a2.eid
HAVING COUNT(*) > 1;

此查询执行连接以将Assignment表中的行与同一表中具有相同项目和不同员工的其他行匹配。我们<用来比较员工 ID,所以我们不会得到重复的配对。

然后我们GROUP BY用来确保每对员工只有一行。

HAVING子句仅选择具有多行的组,即一起从事多个项目的员工对。

于 2009-11-26T20:28:46.880 回答
1

这就是我写它的方式,与比尔写的非常相似,不同之处在于在关系表中 (emp_id, prj_id) 上没有唯一约束的情况下计算不同的项目:

SELECT r1.emp_id, r2.emp_id, COUNT(DISTINCT r1.prj_id) cntProjects
  FROM r_emp_prj r1, r_emp_prj r2
 WHERE r1.emp_id < r2.emp_id
   AND r2.prj_id = r1.prj_id
 GROUP BY r1.emp_id, r2.emp_id HAVING COUNT(DISTINCT r1.prj_id) > 1

如果关系表还存储项目中人员的角色(dev、lead、q&a 等),则关系表中可能有多个条目用于相同的 (emp_id, prj_id) 对。


这也会检索名称:

SELECT r1.emp_id, emp1.name,
       r2.emp_id, emp2.name,
       COUNT(DISTINCT r1.prj_id) cntProjects
  FROM r_emp_prj r1, r_emp_prj r2,
       emp emp1, emp emp2
 WHERE r1.emp_id < r2.emp_id
   AND r2.prj_id = r1.prj_id
   AND emp1.id = r1.emp_id
   AND emp2.id = r2.emp_id
 GROUP BY r1.emp_id, emp1.name, r2.emp_id, emp2.name
HAVING COUNT(DISTINCT r1.prj_id) > 1
于 2009-11-26T21:43:18.943 回答
1

这可以帮助你吗?

select ass1.eid, ass2.eid 
from Assignment ass1         
join Assignment ass2 on ass1.pid = ass2.pid
where ass1.eid < ass2.eid
group by ass1.eid, ass2.eid
having COUNT(0) > 1
于 2009-11-26T20:32:05.470 回答