如何用关系代数找到 MAX?

Posted

技术标签:

【中文标题】如何用关系代数找到 MAX?【英文标题】:How can I find MAX with relational algebra? 【发布时间】:2011-07-26 12:10:32 【问题描述】:

使用数据库,如何使用关系代数找到 MAX?

【问题讨论】:

【参考方案1】:

假设你有一个关系,A,只有一个属性,'a'(减少一个更复杂的关系是关系代数中的一项简单任务,我相信你已经到了这一步),所以现在你想要求 A 中的最大值。

一种方法是找到 A 与其自身的叉积,一定要重命名“a”,这样你的新关系就具有不同名称的属性。例如:

(将“a”重命名为“a1”)X(将“a”重命名为“a2”)

现在选择'a1'

(A x A) - (select 'a1' < 'a2') ((rename 'a' as 'a1')(A) x (rename 'a' as 'a2')(A))

然后使用 project 运算符将其缩减为单个列,正如 Tobi Lehman 在下面的评论中所建议的那样。

如果我没记错的话,可以用关系代数符号来写。请注意,最终重命名(即 ρ)只是为了得到一个与原始关系具有相同名称的属性:

ρa/a1a1((A x A) - σa1 (ρa1/a (A) x ρa2/a(A))))

【讨论】:

只是一个小小的选择,但是集合差异表达式 A-(...) 应该是 (AxA - (...)),因为右手集合中充满了对。然后,在减去所有对之后,使用投影算子将其提取出来。 这个答案只是部分正确。首先,我不相信A x A 的定义很好,因为AA 具有共同的属性(显然因为它们具有相同的模式)并且关系不能具有重复的属性。您自己注意到了这一点,我想您只是忘记对左侧笛卡尔积执行与右侧相同的重命名。 此外,您将A 的笛卡尔积与它自己的差,以及A 的笛卡尔积的所有元组与a1 &lt; a2 的自身之差。这导致a1 &gt;= a2 的关系。最后,您投影到a1 并将a1 重命名为a,留下与您开始时相同的关系A 实例。我不知道为什么这个答案在没有得到纠正的情况下得到了这么多的赞成票,我的推理可能有问题吗? @idipous answer的最后一部分是问题的正确答案。 @gblomqvist 是的,你是对的,我查看了编辑历史,最初只有 A - ... 和一条评论说你仍然需要投影,但后来我根据上面 tlehman 的评论更改了它。 idipous 的回答比较完整【参考方案2】:

我今天要自己解决这个问题,只需要我的两分钱。

假设我们有 A = 1,2,3

如果你使用

A x A - (select 'a1' < 'a2') ((rename 'a' as 'a1')(A) x (rename 'a' as 'a2')(A))

您不会得到单个最大值,而是两列,例如 1|1、2|1,3|2,3|1,3|2,3|3

只有 3 个的方法是

project(a)A - project(a1)((select 'a1' < 'a2') ((rename 'a' as 'a1')(A) x (rename 'a' as 'a2')(A)))

至少这是我在类似情况下必须做的。

希望对某人有所帮助

【讨论】:

【参考方案3】:

假设我们与属性 A 和值 1,2,3 有关系

A

1
2
3

所以现在.. 项目 A 值并用 A1 重命名

A1
1
2
3

再次 项目 A 值并用 A2 重命名

A2
1
2
3

A2&lt;A1 一起加入,即\join_A2&lt;A1 所以 - 输出模式:(A2 整数,A1 整数)

A2<A1

1|2
1|3
2|3

总是听到 A2 值会小于 A1,因为我们 join 喜欢那样(a2&lt;a1

现在项目 A2 的输出如下所示

A2
1
2

现在与原始属性不同

A diff A2

A
1
2
3

 diff

A2
1
2

输出为3最大值

【讨论】:

【参考方案4】:

我现在已经忘记了大部分 relational algebra 语法。仅使用 SELECTPROJECTMINUSRENAME 的查询将是

SELECT v1.number
FROM values v1
MINUS
SELECT v1.number
FROM values v1 JOIN values v2 ON v2.number > v1.number

希望你能翻译!

【讨论】:

【参考方案5】:

我知道这是旧的,但这里有一个手写的公式,可能会很方便!

关系 A:1,2,3,4

1. First we want to PROJECT and RENAME relation A
2. We then to a THETA JOIN with the test a1<a2
3. We then PROJECT the result of the relation to give us a single set of values 
   a1: 1,2,3 (not max value since a1<a2)

4. We then apply the difference operator with the original relation so: 
   1,2,3,4 --- 1,2,3 returns 4

   4 is the Max value.

【讨论】:

@gudthing 认为公式有错误,因为 - 运算符周围的两个表达式应该改变它们的位置。 r1(X) 和 r2(X) 的差异表示为 r1 - r2 并且是 X 上的关系,包含属于 r1 而不是 r2 的元组 请use text, not images/links, for text (including code, tables & ERDs)。使用图像仅是为了方便补充文本和/或无法在文本中给出的内容。永远不要给出没有图例/键的图表。如果您有代表,请使用编辑功能内联,而不是链接 - 使您的帖子独立。【参考方案6】:

求最大值:

策略:

    找出那些不是MAXx

    A 关系重命名为d,以便我们可以将每个A x 与所有其他关系进行比较。

    使用set difference 查找在前面步骤中未找到的A x

查询是:

【讨论】:

假设 A 有另一列 y,并且要求您选择 ymax x,您会怎么做?谢谢。 请use text, not images/links, for text (including code, tables & ERDs)。使用图像仅是为了方便补充文本和/或无法在文本中给出的内容。永远不要给出没有图例/键的图表。如果您有代表,请使用编辑功能内联,而不是链接 - 使您的帖子独立。【参考方案7】:

 Project x(A) - Project A.x
(Select A.x < d.x (A x Rename d(A)))

【讨论】:

【参考方案8】:

关系代数(通过比较过滤)

最近这个问题在数据库模块中作为练习材料出现,当我四处寻找帮助时,我找不到任何好的答案。 “Md. Rezwanul Haque”的答案是正确的,但它并没有得到真正的解释,因为它依赖于先验知识(如果你不了解笛卡尔积)。

所以,这是我的解释的答案,希望这能让一些人更容易:

    TABLE: PEOPLE
PEOPLE.name PEOPLE.age
'Jack'      16
'Megan'     15
'Harry'     14
'Lilly'     16
'Michael'   8

这个想法是"Collect what you don't want and remove it from what you have; leaving you with what you want."

第 1 步(构建要查询的表)

当使用SELECTION 过滤时,我们只能比较我们拥有的元组中的内容。这意味着我们需要向这些元组添加我们想要比较的数据。

因此,我们需要将 PEOPLE 表与我们想要比较的数据合并。这可以使用x (Cartesian Product) Operator

类似这样的:PEOPLE x PEOPLE 但是我们不能这样做,因为结果表看起来像这样:

           TABLE: PEOPLE x PEOPLE
PEOPLE.name PEOPLE.age PEOPLE.name PEOPLE.age 
'Jack'      16         'Jack'      16

我们有duplicate Attribute names,这意味着我们需要为PEOPLE 表创建一个Copy,它有一个不同的名称供我们参考。否则我们不能使用x Cartesian Product Operator,因为它要求所有属性在结果表中都是唯一的,你不能有两个PEOPLE.name属性。

这是我们使用RENAME Operator 的地方,看起来像这样:

PEOPLE ⨯ (ρ ALT (PEOPLE))

我在这里所做的是使用Cartesian Product 合并PEOPLEALT 其中ALTPEOPLE renamedALT

这会给我们一个看起来有点像这样的表:

          TABLE: PEOPLE x ALT
PEOPLE.name  PEOPLE.age ALT.name  ALT.age
'jack'       16         'jack'    16
'jack'       16         'megan'   15
'jack'       16         'harry'   14
'jack'       16         'lilly'   16
'jack'       16         'michael' 8

(结果表是 (PEOPLE.size * PEOPLE.size) = 5*5,其中 size 是元组的数量)其中 PEOPLE 的每个值都与 ALT 的每个值相对应

第 2 步(选择)

现在我们可以过滤所有值并获取我们不想要的值。所以假设我只想要PEOPLE 中最年长的人,这个问题可以改写为:Only people who are not younger than someone 所以我们只抓那些比某人年轻的人。我们这样做是因为it's easier to Query for what we don't want that what we do want

所以,我们的Predicate 将是:PEOPLE.age &lt; ALT.age,我们只选择are younger than someone 的人。

如果我们将Predicate 反转为PEOPLE.age &gt; ALT.age,我们将得到不是最年长的人but who are older than at least one person。这可以帮助我们获取the youngest的人

像这样给我们SELECTION

(σ (PEOPLE.age < ALT.age) (PEOPLE x (ρ ALT (PEOPLE))))

这将产生一个像这样的表:

TABLE: (σ (PEOPLE.age < ALT.age) (PEOPLE x (ρ ALT (PEOPLE))))

PEOPLE.age  PEOPLE.name  ALT.name  ALT.age 
'megan'     15           'jack'    16
'megan'     15           'lilly'   16
'harry'     14           'jack'    16
'harry'     14           'megan'   15
'harry'     14           'lilly'   16
'michael'   8            'jack'    16
'michael'   8            'megan'   15
'michael'   8            'harry'   14
'michael'   8            'lilly'   16

结果是比某人年轻的人,以及他们比谁年轻。但是我们的查询是:Only people who are not younger than someone,这与此完全相反。所以这不是我们的目标,我们需要做更多的事情。如果你这样做:

π PEOPLE.name PEOPLE.age (σ (PEOPLE.age < ALT.age) (PEOPLE x (ρ ALT (PEOPLE))))

这将为我们提供一个包含megan, harry, and michael 的表格这是一个包含以下内容的表格:Only people who are younger than someone

第 3 步(获得我们的决赛桌)

现在我们有一个由Only people who are younger than someone 组成的表,但我们想要的是Only people who are not younger than someone,所以我们需要做的是remove all of the people who are younger than someone from the PEOPLE Table to give us only those who are not younger than someone

所以我们需要使用Subtraction Operation 从我们的PEOPLE table 中删除这些元组。这给了我们最终的查询:

PEOPLE - (π PEOPLE.name PEOPLE.age (σ (PEOPLE.age < ALT.age) (PEOPLE x (ρ ALT (PEOPLE)))))

生成下表:

PEOPLE - (π PEOPLE.name PEOPLE.age (σ (PEOPLE.age < ALT.age) (PEOPLE x (ρ ALT (PEOPLE)))))

PEOPLE.name PEOPLE.age
'jack'      16
'lilly'     16

Jack 和 Lilly 是 only people in PEOPLE who are NOT Younger than someone

【讨论】:

以上是关于如何用关系代数找到 MAX?的主要内容,如果未能解决你的问题,请参考以下文章

实现关系代数的语言特性

数据库关系代数:如何找到在“环球影城”制作的所有电影中扮演过角色的演员?

等价关系与抽象代数的研究对象

数据库的关系代数表达式

关系代数 - 笛卡尔积与自然连接?

关系代数演算So Easy