MySQL - 这个查询如何执行关系划分?

时间:2014-03-27 05:03:03

标签: mysql sql relational-division

我需要创建一个查询,在MySQL中执行两个表之间的关系划分。经过研究后,我发现以下查询将执行关系划分(并且工作正常)但无论我怎么努力,我无法弄清楚它是如何或为什么起作用。< / strong>

以下是2个表格:

mysql> SELECT * FROM Works_on;
+-----------+-----+-------+
| Essn      | Pno | Hours |
+-----------+-----+-------+
| 123456789 |   1 |  32.5 |
| 123456789 |   2 |   7.5 |
| 333445555 |   1 |   0.0 |
| 333445555 |   2 |  10.0 |
| 333445555 |   3 |  10.0 |
| 333445555 |  10 |  10.0 |
| 333445555 |  20 |  10.0 |
| 333445555 |  30 |   0.0 |
| 453453453 |   1 |  20.0 |
| 453453453 |   2 |  20.0 |
| 666884444 |   3 |  40.0 |
+-----------+-----+-------+

mysql> SELECT * FROM Project;
+-----------------+---------+-----------+------+
| Pname           | Pnumber | Plocation | Dnum |
+-----------------+---------+-----------+------+
| ProductX        |       1 | Bellaire  |    5 |
| ProjectY        |       2 | Sugarland |    5 |
| ProjectZ        |       3 | Houston   |    5 |
| Computerization |      10 | Stafford  |    4 |
| Reorganization  |      20 | Houston   |    1 |
| Newbenefits     |      30 | Stafford  |    4 |
+-----------------+---------+-----------+------+

SQL Fiddle

问题:查找处理Project表中列出的所有项目的员工的Essn。因此,基于Pnumber,基本上Works_on除以Project。

我写的查询是:

mysql> SELECT DISTINCT Essn FROM Works_on w1 
WHERE NOT EXISTS 
(SELECT * FROM Project p 
    WHERE NOT EXISTS 
    (SELECT * FROM Works_on w2
        WHERE w2.Essn = w1.Essn AND w2.Pno = p.Pnumber));
+-----------+
| Essn      |
+-----------+
| 333445555 |
+-----------+

请帮助我了解此查询的工作原理。特别是,最里面的查询让我很困惑。

1 个答案:

答案 0 :(得分:1)

你知道,我会坚持这个:

SELECT Essn
   FROM Works_on 
 WHERE Pno IN (SELECT Pnumber 
                 FROM Project)
GROUP BY 
       Essn
HAVING COUNT(*) = (SELECT COUNT(*)
                 FROM Project);

我相信有一些perfomance advantage(反对your query),也有明确的逻辑结构。

SQL Fiddle

P.S。附带建议 - 如果你想了解某些东西的逻辑,那就试试吧。即使你不理解 - 有一个好的秘诀,你会找到另一个解决方案(可能是更好的解决方案)