涉及'for all'的SQL查询

时间:2011-10-18 07:24:02

标签: sql plsql relational-division

我无法获得有关如何为以下架构为A和B编写SQL查询的提示。

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

一个。所有员工参与的计划名称

     

B中。参加其所有部门的员工姓名   程序

任何指导方针都会有所帮助。

3 个答案:

答案 0 :(得分:3)

您需要的关系运算符是division,通常称为"the supplier who supplies all parts"

需要考虑的事项是exact division或余数除以及如何处理空除数。

更新:只是为了澄清,SQL缺少明确的除法运算符或关键字**。但是,可以使用其他运算符在SQL中实现关系除法。由于“家庭作业”标签,我不会发布一个有效的例子。但我通常使用的那个类似于this link处的“具有集合运算符的分区”示例。

请注意,@Dylan Smith是通常所说的“Celko's division”,@ tobyodavies的答案使用了通常所说的“Date's division”的变体(Date不会使用外连接而是使用第二个{{ 1}})。但也许他们确实彻底重塑了这些成熟的方法,谁知道呢? ;)

**同样适用于许多其他关系运营商,例如SQL没有半差分运算符,但可以使用其他SQL运算符执行,例如NOT EXISTSNOT INNOT EXISTS

答案 1 :(得分:1)

没试过这些,但这就是我的想法:

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 :(得分:1)

使用WHERE NOT EXISTS和外部联接

对于所有通用程序:

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

这应该很容易解释 - 选择所有没有员工参与的程序


对于所有热情的员工:

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

再次 - 选择在该员工未参与的同一部门中没有程序的所有雇员。


如果您熟悉形式逻辑,这可能看起来很熟悉 - 通用量化通常根据否定的存在资格来定义