SQL queries involving ' for all' [closed]

吃可爱长大的小学妹 提交于 2019-11-30 20:54:03

问题


I could not get a hint on how to write SQL queries for A and B for the following schema.

Programme (Pid:int, Department:string...)
Employee (Eid:int, Department:string..)
Participation (Pid:int, Eid:int, ..)

A. Names of programmes participated by all employees

B. Names of employees participating in all his department's programmes.

Any guidelines would be helpful.


回答1:


Haven't tried these, but this is what I would be thinking:

SELECT pg.Name 
FROM Participation AS p INNER JOIN Programme AS pg ON p.Pid = pg.Pid
GROUP BY p.Pid 
HAVING COUNT(*) = (SELECT COUNT(*) FROM Employeee)



SELECT e.Name 
FROM Participation AS p INNER JOIN Employee AS e ON p.Eid = e.Eid
                        INNER JOIN Programme AS pg ON pg.Pid = p.Pid
WHERE pg.Department = e.Department
GROUP BY p.Eid, e.Department, e.Name
HAVING COUNT(*) = (SELECT COUNT(*) 
                   FROM Programme AS pg2 
                   WHERE pg2.Department = e.Department)



回答2:


The relational operator you require is division, popularly known as "the supplier who supplies all parts".

Things to consider are whether exact division or division with remainder and how to handle an empty divisor.

UPDATE: just to clarify, SQL lacks an explicit division operator or keyword**. However, relational division can be achieved in SQL using other operators. I'll refrain from posting a working example because of the 'homework' tag. But the one I usually use is similar to the "Division with Set Operators" example at this link.

Note that @Dylan Smith's is what is commonly known as "Celko's division" and @tobyodavies's answer uses a variation on what is commonly known as "Date's division" (Date wouldn't use an outer join but instead a second NOT EXISTS). But maybe they really did reinvent these well-established approaches themselves, who knows? ;)

** the same applies to many other relational operators e.g. SQL has no semi-difference operator but can be performed using other SQL operators e.g. NOT IN, NOT EXISTS, EXCEPT, etc.




回答3:


Use WHERE NOT EXISTS and Outer Joins

For all universal Programmes:

SELECT * FROM Programme
WHERE NOT EXISTS (SELECT * FROM 
                  (Participation NATURAL JOIN Programme) LEFT JOIN Employee
                      USING (Eid,Department) 
                  WHERE Employee.Eid IS NULL)

This should be fairly easy to explain - selects all programs where the is no employee not participating


For all enthusiatic employees:

SELECT * FROM Employee
WHERE NOT EXISTS (SELECT * FROM 
                  Employee LEFT JOIN Participation 
                      USING (Eid,department) 
                  WHERE Participation.Eid IS NULL)

Again - selects all employyes where there are no programs in the same department in which that employee is not participating.


This may look familiar if you are familiar with formal logic at all - universal quantification is generally defined in terms of negated existential qualification



来源:https://stackoverflow.com/questions/7803775/sql-queries-involving-for-all

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!