查询按计数过滤

时间:2011-05-11 23:02:34

标签: sql oracle

鉴于这些表格:

Employee(ssn, name, sex, address, salary, bdate, dno, superssn)
fk:superssn is ssn in Employee
fk:dno is dnumber in Department

Department(dnumber, dname, mgrssn, mgrstartdate)
fk:mgrssn is ssn in Employee

Dept_locations(dnumber, dlocation)
fk:dnumber is dnumber in Department

Project(pnumber, pname, plocation, dnum)
fk:dnum is dnumber in Department

Dependent(essn, dependent_name, sex, bdate, relationship)
fk: essn is ssn in Employee

Works_on(essn,pno,hours)
fk: essn is ssn in Employee; pno is pnumber in Project

我需要检查每个部门的名称以及有两个地点的部门的部门经理姓名......

到目前为止我有这个问题

SELECT D.dname, D.mgrssn
FROM department D, dept_locations DL
WHERE D.dnumber = dl.dnumber
Group by D.dname, D.mgrssn

我现在得到了三个非重复的部门。如何将此限制为具有两个位置的部门?

3 个答案:

答案 0 :(得分:2)

SELECT D.dname, D.mgrssn
FROM Department D, Dept_locations DL
WHERE D.dnumber = DL.dnumber
GROUP BY D.dname, D.mgrssn
HAVING COUNT(*) >= 2            --- for 2 or more locations

最好使用INNER JOIN(或简称JOIN)代替WHERE来加入相关的表格。请注意与先前查询的差异。两者都会返回相同的结果:

SELECT D.dname, D.mgrssn
FROM Department D
    JOIN Dept_locations DL
        ON D.dnumber = DL.dnumber
GROUP BY D.dname, D.mgrssn
HAVING COUNT(*) >= 2          

如果您还想显示经理的姓名,您还必须加入员工表(并相应地分组):

SELECT D.dname
     , D.mgrssn
     , E.name
FROM Department D
    JOIN Employee E 
        ON E.ssn = D.mgrssn
    JOIN Dept_locations DL
        ON D.dnumber = DL.dnumber
GROUP BY D.dname
       , D.mgrssn
       , E.name
HAVING COUNT(*) >= 2       

答案 1 :(得分:1)

正好两个地点:

SELECT d.name AS dept_name,
       e.name AS mgr_name
  FROM DEPARTMENT d
  JOIN EMPLOYEE e ON e.ssn = d.mgrssn
 WHERE EXISTS (SELECT NULL
                 FROM DEPT_LOCATIONS dl
                WHERE dl.dnumber = d.dnumber
             GROUP BY dl.dnumber
               HAVING COUNT(*) = 2)

对于两个或更多地点:

SELECT d.name AS dept_name,
       e.name AS mgr_name
  FROM DEPARTMENT d
  JOIN EMPLOYEE e ON e.ssn = d.mgrssn
 WHERE EXISTS (SELECT NULL
                 FROM DEPT_LOCATIONS dl
                WHERE dl.dnumber = d.dnumber
             GROUP BY dl.dnumber
               HAVING COUNT(*) >= 2)

请记住

DEPARTMENT表格有mgrstartdate,因此您需要对其进行检查 - 我提供的两个示例将向您展示除了当前经理之外的所有历史经理,因为没有过滤mgrstartdate

答案 2 :(得分:0)

select dname, name
from Department, Employee, Dept_locations
where mgrssn = ssn
and Department.dnumber = Dept_locations.dnumber