Mysql 从特定范围中选择全部
我有以下问题: 查找在受控制的所有项目上工作的员工的姓名 第五部门 我的表格包括员工(SSN)、工作(SSN、PNNumber)、项目(PNNumber、DNNumber) 我在试着找出“全部”部分。我尝试了不同的方法,但我要做的是创建一个规范化的查询树,所以我需要确保SQL查询可以转换为该树 我尝试了以下方法:Mysql 从特定范围中选择全部,mysql,sql,relational-database,relational-algebra,Mysql,Sql,Relational Database,Relational Algebra,我有以下问题: 查找在受控制的所有项目上工作的员工的姓名 第五部门 我的表格包括员工(SSN)、工作(SSN、PNNumber)、项目(PNNumber、DNNumber) 我在试着找出“全部”部分。我尝试了不同的方法,但我要做的是创建一个规范化的查询树,所以我需要确保SQL查询可以转换为该树 我尝试了以下方法: SELECT E.Fname, E.Lname FROM Employee AS E, works_on AS W WHERE E.SSN IN ALL ( SELECT SSN FR
SELECT E.Fname, E.Lname
FROM Employee AS E, works_on AS W
WHERE E.SSN IN ALL
(
SELECT SSN
FROM Projects AS P
WHERE W.SSN = E.SSN AND W.PNUMBER = P.PNUMBER AND P.DNUMBER = 5
);
但我不确定它是否会起作用,因为我总共使用了。我还尝试了一件事,那就是按员工计算每个小组的工作量,以及项目的数量
最终我发现:
select fname, lname
from employee
where not exists ( (select pnumber from project where dnum = 5)
MINUS
(select pno from works_on where essn = ssn)
);
但我没能把它变成一棵树
你有什么建议我可以用吗?是的,这是家庭作业
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (employee_id SERIAL PRIMARY KEY);
DROP TABLE IF EXISTS employee_project;
CREATE TABLE employee_project (employee_id INT NOT NULL, project_id INT NOT NULL,PRIMARY KEY(employee_id,project_id));
DROP TABLE IF EXISTS projects;
CREATE TABLE projects(project_id SERIAL PRIMARY KEY, department_id INT NOT NULL);
INSERT INTO employees VALUES (101),(102),(103);
INSERT INTO employee_project VALUES (101,5004),(101,5005),(101,5006),(101,5007),(102,5004),(102,5007),(102,5008),(103,5006),(103,5007),(103,5008);
INSERT INTO projects VALUES (5004,1),(5005,2),(5006,5),(5007,5),(5008,4),(5009,3);
Consider the following:
SELECT *
FROM employees e
JOIN projects p
LEFT
JOIN employee_project ep
ON ep.employee_id = e.employee_id
AND ep.project_id = p.project_id
WHERE p.department_id = 5;
+-------------+------------+---------------+-------------+------------+
| employee_id | project_id | department_id | employee_id | project_id |
+-------------+------------+---------------+-------------+------------+
| 101 | 5006 | 5 | 101 | 5006 |
| 102 | 5006 | 5 | NULL | NULL |
| 103 | 5006 | 5 | 103 | 5006 |
| 101 | 5007 | 5 | 101 | 5007 |
| 102 | 5007 | 5 | 102 | 5007 |
| 103 | 5007 | 5 | 103 | 5007 |
+-------------+------------+---------------+-------------+------------+
从这个结果中,我们可以得出两个观察结果,其中任何一个都有助于解决这个问题
结果中不同项目的数量等于用户101和103旁边列出的不同项目的数量(即,这些数字出现在第4列中的次数)
用户102的结果为空,这意味着他们没有参与该部门的所有项目
从这个结果中,我们可以得出两个观察结果,其中任何一个都有助于解决这个问题
结果中不同项目的数量等于用户101和103旁边列出的不同项目的数量(即,这些数字出现在第4列中的次数)
用户102的结果为空,这意味着他们没有参与该部门的所有项目
我认为group\u concat()
是最简单的解决方案。假设没有重复项,您可以获得部门5的所有项目,如下所示:
select group_concat(p.pnumber order by p.pnumber)
from projects p
where dnumber = 5;
然后,您可以对员工执行相同的操作并匹配他们:
select e.ssn, group_concat(wo.pnumber order by wo.pnumber)
from works_on wo
where wo.pnumber in (select p.pnumber from projects p where p.dnumber = 5)
group by e.ssn;
最后将两者匹配,例如在having
子句中:
select e.ssn, group_concat(wo.pnumber order by wo.pnumber) as projects
from works_on wo
where wo.pnumber in (select p.pnumber from projects p where p.dnumber = 5)
group by e.ssn
having projects = (select group_concat(p.pnumber order by p.pnumber)
from projects p
where dnumber = 5
);
另一种使用关系逻辑的方法如下:
select e.ssn
from employees e cross join
projects p left join
works_on wo
on e.ssn = wo.ssn and p.pnumber = wo.pnumber
where p.dnumber = 5
group by e.ssn
having count(wo.snn) = count(*); -- no NULL values
我认为group\u concat()
是最简单的解决方案。假设没有重复项,您可以获得部门5的所有项目,如下所示:
select group_concat(p.pnumber order by p.pnumber)
from projects p
where dnumber = 5;
然后,您可以对员工执行相同的操作并匹配他们:
select e.ssn, group_concat(wo.pnumber order by wo.pnumber)
from works_on wo
where wo.pnumber in (select p.pnumber from projects p where p.dnumber = 5)
group by e.ssn;
最后将两者匹配,例如在having
子句中:
select e.ssn, group_concat(wo.pnumber order by wo.pnumber) as projects
from works_on wo
where wo.pnumber in (select p.pnumber from projects p where p.dnumber = 5)
group by e.ssn
having projects = (select group_concat(p.pnumber order by p.pnumber)
from projects p
where dnumber = 5
);
另一种使用关系逻辑的方法如下:
select e.ssn
from employees e cross join
projects p left join
works_on wo
on e.ssn = wo.ssn and p.pnumber = wo.pnumber
where p.dnumber = 5
group by e.ssn
having count(wo.snn) = count(*); -- no NULL values
你能找到没有的员工吗?(在我看来,SSN是一个糟糕的主键)@草莓我们正在使用一个示例数据库。是的,如果你能找到一个解决方案,找到那些没有的员工,然后我们从所有员工中减去,那就没关系了。我有,但这不是我的homework@Strawberry哈哈哈,好吧,我明白了,所以你只是暗示我能做什么。如果我找不到所有员工,那么我怎么能找不到所有员工?你能找到没有的员工吗?(在我看来,SSN是一个糟糕的主键)@草莓我们正在使用一个示例数据库。是的,如果你能找到一个解决方案,找到那些没有的员工,然后我们从所有员工中减去,那就没关系了。我有,但这不是我的homework@Strawberry哈哈哈,好吧,我明白了,所以你只是暗示我能做什么。如果我找不到所有员工,那么我怎么能找到所有员工呢?好的,那么你在这里做的是将每个员工与每个项目合并,并在没有空值的地方选择所有员工。听起来很棒!谢谢@问题再次出现——如果允许的结果中有空值,那么您没有明确提出问题。@philipxy我的问题只是需要一个可以转换为查询树的解决方案。我没有提到空值是不允许的。好吧,你在这里做的是将每个员工与每个项目合并,并选择所有没有空值的地方。听起来很棒!谢谢@问题再次出现——如果允许的结果中有空值,那么您没有明确提出问题。@philipxy我的问题只是需要一个可以转换为查询树的解决方案。我没有提到空值是不允许的。我想我们可以在回答问题时使用distinct。谢谢@如果一个项目的结果是一个字符串编码的列表是一个允许的结果,那么你还没有明确提出这个问题。我想我们可以在你的答案中使用distinct。谢谢@如果一个项目的结果是一个字符串编码的列表,这是一个允许的结果,那么您还没有明确提出这个问题。