如何查找所有提供过所有被30岁以上人吃过的比萨饼的比萨店?

17
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我正在参加斯坦福数据库课程,其中有一个问题,我们需要使用关系代数找到所有提供30岁以上人吃过的每种披萨的比萨店。

这个问题包含一个小型数据库,有四个关系:

Person(name, age, gender)       // name is a key
Frequents(name, pizzeria)       // [name,pizzeria] is a key
Eats(name, pizza)               // [name,pizza] is a key
Serves(pizzeria, pizza, price)  // [pizzeria,pizza] is a key

我知道如何找到30岁以上人吃的披萨,并对它们进行交叉组合,这样我就可以检查哪家比萨店都有。

我可以列出所有提供这些披萨的比萨店,但我不知道如何删除只有一种组合(如Dominos)的比萨店。

Chicago Pizza   cheese  cheese
Chicago Pizza   cheese  supreme
Chicago Pizza   supreme cheese
Chicago Pizza   supreme supreme
Dominos         cheese  cheese
Dominos         cheese  supreme

问答论坛告诉我们要使用除法,并指向多个演示文稿。虽然我知道这个操作的结果是什么,但我不太明白如何将公式转换为关系代数语法。

有人能否解释一下我错过了什么,希望不要直接给出解决方案?


这个问题经常被问到。请参见http://stackoverflow.com/questions/7731877/can-all-sql-queries-be-represented-in-relational-algebra-domain-and-tuple-relat/7733636#7733636。你所询问的细节在我对那个问题的回答中。 - Erwin Smout
我不知道,但是你的回答并没有帮助到我。我在将自己的数据转换为除法查询时遇到了问题,所以把我发送到另一个完全无关的示例并没有帮助我解决它。 - Ivo Flipse
9个回答

9

这绝对是关系代数中除法运算符的概念。

但我在那门课上尝试过了。关系代数语法不支持除法运算符。所以我使用了差集和交集。这是我的解决方案:

\project_{pizzeria}(Serves)
\diff
\project_{pizzeria}(
    (\project_{pizzeria}(Serves) 
    \cross 
    \project_{pizza}(\project_{name}(\select_{age>30}(Person))\join Eats))
    \diff
    \project_{pizzeria,pizza}(Serves)
)

8
  1. 在幻灯片 6 上,请注意 n 是 (3 1 7)

  2. 在下一张幻灯片上,o / n 的结果为 (4 8)

  3. 如果 o 同样也有 (12 3)(12 1),但不包括 (12 7),那么 12 将不是 o / n 的一部分。

您应该能够在第 16 张幻灯片上填写一个示例,并计算出结果。

  1. In your case, we take ɑ to be:

    Chicago Pizza   cheese  cheese
    Chicago Pizza   cheese  supreme
    Chicago Pizza   supreme cheese
    Chicago Pizza   supreme supreme
    Dominos         cheese  cheese
    Dominos         cheese  supreme
    
  2. Then we take β to be:

    cheese cheese
    cheese supreme
    supreme cheese
    supreme supreme
    
  3. The result of ɑ / β would then be:

    Chicago Pizza
    
不包括在内,因为它缺少和。

如果那是alpha,那么alpha的A-B投影会是什么(见第18张幻灯片)?我仍然有一些困难将该公式转化为具体内容。 - Ivo Flipse
@IvoFlipse:幻灯片上说,对于该投影计算所有可能的属性配对。 - Tamara Wijsman
请确保您的帖子自包含。这篇帖子本身毫无意义。 - philipxy

6

哇,终于有一个例子甚至使用关系代数! - Ivo Flipse

3
这是另一个回答的注释。我的大脑很疼,所以我尝试了先前发布的简明而完整的答案,它起作用了。但这仅仅是“授人以鱼”,所以我必须看看背后的东西。
以下是ChrisChen3121在2014年1月22日提出的解决方案,只更改了括号、注释和换行。大多数括号与其匹配垂直对齐。希望这能让事情变得更容易看到。在美学重写的代码之后,是为了可视化/概念化解决方案而产生的中间关系。
长话短说:
- 寻找目标披萨; - 使用\cross,构建一个幻想超集列表,好像所有的比萨店都提供了这些披萨; - 从中减去所有“实际上提供”的披萨,从而创建一个“缺失的”列表; - 最后,从[新的]“现实”中减去“缺失”的……就是这样。
\project_{pizzeria}(Serves)// “Actual” list of what pizzerias serve. Results shown below. 
\diff
\project_{pizzeria}
(// After the diff, this is a list of "What's Missing". Results shown below
    (// Super-set of all pizzerias combined with all "over30pies". Results shown below 
     // NOTE: Some combos here do not match reality
        \project_{pizzeria}(Serves)
        \cross
        (// "over30pies": Within these parentheses produces table shown below
            //Next line is what I used, it’s effectively equivalent, yes.
            //roject_{pizza} (                \select_{age > 30 }  Person  \join Eats)
            \project_{pizza} (\project_{name}(\select_{age > 30 } (Person))\join Eats)
        )
    )
    \diff
    ( // “Actual” list of what pizzerias serve. Results shown below. 
        \project_{pizzeria,pizza}(Serves)
    )
)

//“over30pies”,目标馅饼(指被30岁及以上人群食用的馅饼)

cheese 
supreme

// 所有比萨店和所有目标(“over30pies”)的超级集合 // 注意:某些组合不符合现实。

Chicago Pizza | cheese
Chicago Pizza | supreme
Dominos | cheese
Dominos | supreme
Little Caesars | cheese
Little Caesars | supreme
New York Pizza | cheese
New York Pizza | supreme
Pizza Hut | cheese
Pizza Hut | supreme
Straw Hat | cheese
Straw Hat | supreme

//实际上,哪些披萨店真正提供哪些口味的完整列表

Chicago Pizza | cheese
Chicago Pizza | supreme
Dominos | cheese
Dominos | mushroom
Little Caesars | cheese
Little Caesars | mushroom
Little Caesars | pepperoni
Little Caesars | sausage
New York Pizza | cheese
New York Pizza | pepperoni
New York Pizza | supreme
Pizza Hut | cheese
Pizza Hut | pepperoni
Pizza Hut | sausage
Pizza Hut | supreme
Straw Hat | cheese
Straw Hat | pepperoni
Straw Hat | sausage

//在想象中的“超级套餐”减去“实际”后的差异(剩余部分)。这代表了缺失的内容,也就是“这些比萨店没有提供所列出的必备比萨”。

Dominos | supreme
Little Caesars | supreme
Straw Hat | supreme

3

尝试使用条件进行连接,而不是交叉连接。这些条件将确保您正确匹配记录(仅在两个关系中都包含它们时才包括它们),而不是将第一个关系中的每个记录与第二个关系中的每个记录进行匹配。


1

我根据维基百科得出以下结论:

R:=\project_{pizzeria, pizza} (\select_{age>30} (Person \join Eats \join Serves))

S:=\project_{pizza} (\select_{age>30} (Person \join Eats \join Serves))

最终解决方案:

\project_{pizzeria} (\project_{pizzeria, pizza} (\select_{age>30} (Person \join Eats \join Serves)))

\diff

( \project_{pizzeria} ( ( \project_{pizzeria} (\project_{pizzeria, pizza} (\select_{age>30} (Person \join Eats \join Serves))) \cross \project_{pizza} (\select_{age>30} (Person \join Eats \join Serves)) ) \diff ( \project_{pizzeria, pizza} (\select_{age>30} (Person \join Eats \join Serves)) ) ) )


1

这是将http://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html转换为MySQL的过程。

    mysql>create table parts (pid integer);创建一个名为parts的表,包含一个整型列pid
    mysql>create table catalog (sid integer,pid integer);创建一个名为catalog的表,包含两个整型列sid和pid
    mysql>insert into parts values ( 1), (2), (3), (4), (5);向parts表中插入五条记录,分别是1,2,3,4,5
    mysql>insert into catalog values (10,1);向catalog表中插入一条记录,sid为10,pid为1
mysql>select * from catalog;查询catalog表中所有记录并输出
+------+------+ | sid | pid | +------+------+ | 10 | 1 | | 1 | 1 | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 1 | 5 | +------+------+
mysql> select distict sid,pid from (select sid from catalog) a join parts;从catalog表中选择sid并与parts表连接,输出sid和pid
+------+------+ | sid | pid | +------+------+ | 10 | 1 | | 10 | 2 | | 10 | 3 | | 10 | 4 | | 10 | 5 | | 1 | 1 | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 1 | 5 | +------+------+
mysql>select * from (select distinct sid,pid from (select sid from catalog) a ,parts) b where not exists (select 1 from catalog c where b.sid = c.sid and b.pid = c.pid);从catalog表中选择sid并与parts表连接,输出不在catalog表中的sid和pid
+------+------+ | sid | pid | +------+------+ | 10 | 2 | | 10 | 3 | | 10 | 4 | | 10 | 5 | +------+------+
mysql>select distinct sid from catalog c1 where not exists ( select null from parts p where not exists (select null from catalog where pid=p.pid and c1.sid=sid));从catalog表中选择不包含在parts表中的sid并输出
+------+ | sid | +------+ | 1 | +------+

1

基于所有比萨店至少提供一种比萨的假设,我们将发现人们30岁以上不吃的比萨组合将被所有比萨店出售,除了那些专门销售30岁以上人群喜欢的比萨的店铺。这有帮助吗?


不是很清楚,因为我不知道如何用关系代数表达它。但幸运的是,其他答案帮助我解决了它 :-) - Ivo Flipse

0

嗨,我找到了一种不需要除法运算符的解决方案:

\project_{pizzeria}Serves
\diff
\project_{pizzeria}((\project_{pizza}(\select_{age < 30}Person\joinEats)
\diff\project_{pizza}(\select_{age > 30}Person\joinEats))\joinServes);

========================================================================

就是这么简单。 我做了什么? 在第二部分中,我发现比萨列表中没有包括那些被30岁以上人吃的比萨。

我将它们与比萨店合并,以查看哪些比萨店也为年轻人制作比萨。

我将其与原始比萨店列表区分开来,唯一一个为30岁以上人制作比萨的是芝加哥比萨。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接