3

表:

Show(show_id, title, start_date, duration,singer,hall_id)
Concert(concert_is,date,hour,show_id)
Hall(Hall_id, name, address, capacity)

以上是 3 个表的数据库。我需要将一些简单的 SQL 语句转换为 RA:

SELECT date
FROM Concert C, Show S, Hall H
WHERE C.show_id = S.Show_id
AND S.hall_id = H.hall_id
AND S.singer = 'A'
AND H.name = 'B'

在RA中:

pi date (s(show_id = show_id)Show |><| Concert)

以上不完整,我只需要知道我是否在正确的轨道上。关于 RA 的信息有限。

4

2 回答 2

1

这是使用“自然连接”的一个镜头。另请注意,我没有使用您的元组变量:

pi date (sigma name = 'B' AND singer = 'A' (CONCERT x SHOW x HALL))

上面的表达式是评估 SQL 查询效率最低的方法之一;但是,在语法上它更接近您的 SQL。

这是我使用的查询模板:

pi TargetList sigmaSelection_Condition (REL1 x ... X RELn)

我将很快更新一个使用你的 |><| 的变体。接线员,如果你愿意...

于 2012-08-16T16:23:56.687 回答
1

第一步是将查询变成文字:问的是什么?在这种情况下,我们想要所有音乐会的日期,其中音乐会的表演由“A”演唱,音乐会所在的大厅被命名为“B”。(这一步并不总是必要的——在许多情况下,我们可能会直接从 SQL 生成 RA——但确保你理解你在做什么从来都不是一个坏主意)。

因此,让我们从内到外构建您的 RA 声明。首先,我们要确保无论何时我们同时看一场演出和一场音乐会,我们只是在寻找那场音乐会上的节目,在这种情况下,节目的 id 是音乐会中的一个字段。所以你的直觉使用natural join/|><|是正确的。我一直都知道,除非另有说明,否则自然连接将自动匹配所有等效的列名(尽管我会先检查你老师的标准),所以在这种情况下,我们不需要指定显示的连接条件id 匹配。即使我们这样做了,那也将是连接的下标,而不是 select 语句的一部分。接下来我们要确保当我们看一个大厅和一个节目时,我们只看那个大厅里的节目。所以我们想自然地加入大厅到之前的结果(注意加入的顺序很重要——如果还没有加入表演,你不能自然地加入音乐会和大厅)。

下一步是只获取我们想要的信息行。在这种情况下,select/sigma语句非常简单——只需指定名称和大厅必须是您想要的。最后,我们project/pi只从检索到的行中选择我们想要的数据元素——在这种情况下,我们将只预测日期。在那之后,我们就完成了。到目前为止,从您的 RA 来看,我可以看到您已经按照正确的顺序拥有了所有运算符,您只是缺少操作数!

请注意,还有一些其他事项需要考虑。您可能需要考虑rename/rho在每个表上使用以简化写出的内容。此外,如果您的 RA 需要完全复制 SQL,您将不得不使用重命名,并将您的自然连接替换为cross join/X并将连接条件放在您的 select 语句中。

于 2012-09-23T17:26:14.790 回答