从特定范围中选择ALL

时间:2018-05-03 16:51:30

标签: mysql sql relational-database relational-algebra

我有以下问题:

  

查找处理所有受项目控制的项目的员工姓名   部门编号5。

我拥有的表是员工(SSN),Works_On(SSN,PNumber),项目(PNumber,DNumber)。

我试图找出" ALL"部分。我尝试了不同的方法,但我想要做的是创建一个规范的查询树,所以我需要确保可以将SQL查询转换为该查询。

我尝试过以下方法:

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
);

但我不确定它会起作用,因为我使用了IN ALL。我尝试的另一件事是获取工作的计数和按员工分组,并获得项目的计数。

最终我发现了这个:

select fname, lname
from employee
where not exists ( (select pnumber from project where dnum = 5)
                   MINUS 
                   (select pno from works_on where essn = ssn)
                 );

但我无法将其转换为树。

你有什么建议可以使用吗?是的,它是家庭作业。

2 个答案:

答案 0 :(得分:1)

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 |
+-------------+------------+---------------+-------------+------------+

从这个结果中,我们可以做出两个观察,其中任何一个都可能有助于解决问题。

  1. 结果中不同项目的数量等于用户101和103旁边列出的不同项目的数量(即这些数字在第4列中出现的次数)。
  2. 用户102的结果为空,这意味着他们没有参与该部门的所有项目。

答案 1 :(得分:1)

我认为Better alternative There exists a convenient alternative based on message formats. Assuming entry is an object, you can write: Object entry = new SomeObject(); logger.debug("The entry is {}.", entry); Only after evaluating whether to log or not, and only if the decision is positive, will the logger implementation format the message and replace the '{}' pair with the string value of entry. In other words, this form does not incur the cost of parameter construction when the log statement is disabled. 是最简单的解决方案。假设没有重复项,您可以获得部门5的所有项目:

group_concat()

然后,您可以为员工做同样的事情并匹配他们:

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
                  );