首页 > 解决方案 > 关系代数:仅一起出现的值

问题描述

考虑一家餐厅的员工 ID 表以及他们工作的班次。如果我有一个以 Shifts(ShiftID, EmployeeID) 形式给出的数据方案,其中 Shift 和 EmployeeID 一起构成关系的键,我如何才能找到所有只能一起工作的员工对。也就是说,如果员工 A 仅在员工 B 工作时工作,我想要元组 (A, B) 和 (B, A),反之亦然。

这对于基本的关系代数运算符(选择、项目、叉积、自然连接、重命名)和集合操作(​​联合、相交、差异)是否可行?

样本输入:

轮班员工

1个

1乙

2个

2乙

3℃

预期产出

员工1 员工2

AB

文学学士

我的尝试:

首先取 Shifts 的叉积并选择 ShiftID 相同但 EmployeeID 不同的所有元组(即让所有员工对在同一班次工作)。

然后我尝试将上述结果关系与自身相乘并选择 ShiftID 相同的元组,第一个 EmployeeID 相同但第二个 EmployeeID 不同。我试图获取“DifferentPairs”,因此我在第一个副本中选择了第一个 EmployeeID,在第二个副本中选择了第二个 Employee ID。

但是后来我被卡住了,因为我意识到 Pairs = DifferentPairs 对于有超过 1 对的员工,因为我的第二个交叉产品可能有员工 (A, B | A, C) 和 (A, C | A, B) 所以如果我拿第一个和第四个 ID,我得到 (A, C) 和 (A, B),现在我回到了我开始的地方(不是在我给出的示例中,而是在一般情况下)。

标签: relational-databaserelational-algebra

解决方案


如果员工 A 仅在员工 B 工作时工作,反之亦然。

所以我们想比较A 工作的班次集合和 B 工作的班次集合。

那么使用关系代数很好,因为关系是集合。使用 SQL 会很困难:表不是集合(通常),并且 SQL 对集合运算符的潜力有限。

你没有提到你正在使用哪种类型的 RA。所以我会从 Date & Darwen 的教科书中学习教程 D。特别是 GROUP 运算符,用于投影关系,将其中一个属性的值作为一组保存。我们将把它放在一个临时关系变量中:

WITH ShiftSet := Shifts GROUP { ShiftID AS ShiftSet }

(实际上是按 EmployeeID 分组,所以我们将为每个 Employee 获得一个元组,该 Employee 的班次作为一个名为 ShiftSet 的属性中的集合。)

然后我们将具有相同 ShiftSet 值的 Employee 元组配对;通过自加入的常用技巧(需要重命名)

ShiftSet JOIN (ShiftSet RENAME {EmployeeID as EmpID2})
WHERE EmployeeID NOT = EmpID2
{ALL BUT ShiftSet}

WHERE 条件是清除连接到自身的 Employee 元组。尾随{ALL BUT ...}是将 ShiftSet 投影出去,因此我们得到了对{EmployeeID, EmpID}作为结果。

这对基本的关系代数运算符是否可行?

是的,您列出的那些是可能的。Philipxy 的第一条评论为您提供了提示。您实际上是在进行关系划分:有关这些运算符的等效公式,请参见维基百科。这会导致您使用各种 RA 瘫痪,因此它不会让 SQL 感到尴尬。


推荐阅读