所有部门的sql都会计算那些不在该部门的项目上工作的员工

时间:2018-03-26 12:39:22

标签: sql select subquery

我需要创建一个视图,报告部门名称以及有多少员工不在该部门控制的任何项目上工作。

我知道如何创建一个视图,并且已经找到了通过连接来计算有多少员工为某个部门的项目工作的计数的方法,但是无法弄清楚如何获得不通过连接的员工数量,与该部门配对。这是一般的SQL,并不依赖于特定的DBMS,因此我可能需要避免仅限于特定DBMS的模糊SQL命令。

我已经创建了一个模拟我相信与此问题相关的模式部分:

Create Table DEPARTMENT (Dname VARCHAR(30), Dnumber INTEGER primary key , Mgr_ssn INTEGER, Mgr_start_date Varchar(30));
INSERT INTO Department (Dname,Mgr_ssn,Mgr_start_date) values ('maths',1,'foo');
INSERT INTO Department (Dname,Mgr_ssn,Mgr_start_date) values ('physics',2,'foo');


Create Table PROJECT (Pname VARCHAR(30), Pnumber INTEGER primary key , Plocation varchar(10), Dnum INTEGER);
INSERT INTO PROJECT (Pname,Plocation,Dnum) values ('project','the moon',1);
INSERT INTO PROJECT (Pname,Plocation,Dnum) values ('project','the moon',1);
INSERT INTO PROJECT (Pname,Plocation,Dnum) values ('project','the moon',2);
INSERT INTO PROJECT (Pname,Plocation,Dnum) values ('project','the moon',2);
INSERT INTO PROJECT (Pname,Plocation,Dnum) values ('project','the moon',2);

Create Table EMPLOYEE (Fname VARCHAR(30), SSn INTEGER primary key);
INSERT INTO EMPLOYEE (Fname) VALUES ('rick');
INSERT INTO EMPLOYEE (Fname) VALUES ('rick');
INSERT INTO EMPLOYEE (Fname) VALUES ('rick');
INSERT INTO EMPLOYEE (Fname) VALUES ('rick');
INSERT INTO EMPLOYEE (Fname) VALUES ('rick');

Create Table WORKS_ON (Essn INTEGER,Pno INTEGER, primary key(Essn,Pno));
INSERT INTO WORKS_ON VALUES(1,1);
INSERT INTO WORKS_ON VALUES(2,4);
INSERT INTO WORKS_ON VALUES(3,3);
INSERT INTO WORKS_ON VALUES(4,4);
INSERT INTO WORKS_ON VALUES(4,3);
INSERT INTO WORKS_ON VALUES(4,2);

虽然这是一项学术练习,但这不是一项任务,所以如果我没有完成任务,或者以其他方式获得解决方案的帮助,我将永远不知道如何处理这些类型的查询。

我尝试过的第一件事就是计算每个存在的员工的数量,然后尝试减去为每个部门工作的每个员工的数量,但我无法让算法在所有部门工作行。我无法使用SET Minus和子查询工作来获得其他解决方案。

编辑:我必须得到每个部门负责项目的员工的数量:

SELECT Dnumber, count(*) num_employees_on_projects FROM department d
INNER JOIN PROJECT p on d.Dnumber = p.Dnum
INNER JOIN WORKS_ON w on w.Pno = p.Pnumber 
INNER JOIN EMPLOYEE e on e.Ssn = w.essn
group by Dnumber

1 个答案:

答案 0 :(得分:0)

您需要切换到外部联接以包含不匹配的行。然后你计算最右边的表(WORKS_ON)中的一列,它已知为非NULL,最简单的是连接列:

SELECT Dnumber,
   count(*) as all_employees,
   count(w.Pno) as employees_on_projects,
   count(*) - count(w.Pno) as employees_without_project
FROM department d
LEFT JOIN PROJECT p on d.Dnumber = p.Dnum
LEFT JOIN WORKS_ON w on w.Pno = p.Pnumber 
-- LEFT JOIN EMPLOYEE e on e.Ssn = w.essn -- not needed
group by Dnumber;

编辑:

要将每个部门的数据与可能添加标量子查询的员工总数相关联:

SELECT Dnumber,
   count(w.Pno) as employees_on_projects,
   (SELECT count(*) FROM EMPLOYEE) -- all employees
    - count(w.Pno) as employees_without_project
FROM department d
LEFT JOIN PROJECT p on d.Dnumber = p.Dnum
LEFT JOIN WORKS_ON w on w.Pno = p.Pnumber 
group by Dnumber;

请参阅fiddle