请考虑一张餐厅的员工ID表以及他们的工作班次。如果我有一个按Shifts(ShiftID,EmployeeID)给出的数据方案,其中Shift和EmployeeID共同构成了关系的键,那么我怎么才能找到只能一起工作的所有成对的雇员。也就是说,如果雇员A仅在雇员B工作时工作,反之亦然,我想要元组(A,B)和(B,A)。
使用基本关系代数运算符(选择,项目,叉积,自然连接,重命名)和设置运算符(联合,相交,差)是否可行?
样本输入:
轮班员工
1 A
1 B
2 A
2 B
3 C
预期产量
Employee1 Employee2
A B
BA A
我的尝试
首先获取Shifts的叉积并选择ShiftID相同但EmployeeID不同的所有元组(即,使所有成对的员工在同一班次工作)。
然后,我尝试将上述结果关系的叉积与自身进行选择,并选择ShiftID相同的元组,第一个EmployeeID相同,但第二个EmployeeID不同。我试图获取“ DifferentPairs”,因此我在第一个副本中选择了第一个EmployeeID,在第二个副本中选择了第二个Employee ID。
但是后来我被困住了,因为我意识到对数大于1的员工使用Pairs = DifferentPairs,因为我的第二个叉积可能有(A,B | A,C)和(A,C | A,B)和因此,如果我使用第1个和第4个ID,我会得到(A,C)和(A,B),现在我回到了开始的位置(在我给出的示例中不是,而是一般而言)。
答案 0 :(得分:0)
如果员工A仅在员工B工作时才工作,反之亦然。
因此,我们想将A的班次集与B的班次进行比较。
然后,最好使用关系代数,因为关系是集合。使用SQL会很困难:表通常不是集合,并且SQL对于集合运算符的潜力有限。
您没有提到您正在使用哪种RA。因此,我将从Date&Darwen的教科书中获得教程D。尤其是GROUP运算符,用于投影关系,将其属性之一的值作为一组保存。我们将其放入一个临时关系变量中:
WITH ShiftSet := Shifts GROUP { ShiftID AS ShiftSet }
(实际上是按EmployeeID分组的,因此我们将为每个Employee获取一个元组,并将该雇员的班次作为名为ShiftSet的属性中的一个集合。)
然后我们将具有相同ShiftSet值的Employee元组配对;通过通常的自连接技巧(需要重命名)
ShiftSet JOIN (ShiftSet RENAME {EmployeeID as EmpID2})
WHERE EmployeeID NOT = EmpID2
{ALL BUT ShiftSet}
其中的条件是淘汰加入自己的Employee元组。尾随的{ALL BUT ...}
是要投影ShiftSet的,因此结果是成对的{EmployeeID, EmpID}
。
使用基本关系代数算子可以吗?
是的,您列出的内容是可能的。 Philipxy的第一条评论为您提供了提示。您实际上是在进行关系划分:有关这些运算符的等效提法,请参阅Wikipedia。这导致您陷入各种RA瘫痪,因此不会使SQL感到尴尬。