我正在关注斯坦福数据库课程,并且有一个问题,我们找到了所有的比萨饼,只使用关系代数为超过30岁的人们吃的每个比萨饼提供服务。
问题包括a small database with four relations:
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多个披萨的人吃了它们并制作了它们的交叉产品,所以我可以检查哪个披萨店都有。
我可以列出所有比萨店供应那些披萨,但我不知道如何删除任何只有一个组合的比萨店(如多米诺)。
Chicago Pizza cheese cheese
Chicago Pizza cheese supreme
Chicago Pizza supreme cheese
Chicago Pizza supreme supreme
Dominos cheese cheese
Dominos cheese supreme
问答论坛告诉我们使用除法和point us to several presentations.虽然我得到了动作的结果,但我真的不明白如何将公式转换为关系代数语法。
任何人都可以向我解释我错过了什么,希望没有完全给出解决方案吗?
这绝对是关系代数中除法运算符的概念。
但我尝试了这个课程。 RA Relational Algebra Syntax不支持dev运算符。所以我改用了diff和cross。这是我的解决方案:
\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)
)
(3 1 7)
。o / n
导致(4 8)
。o
也有(12 3)
和(12 1)
而不是(12 7)
,12将不会是o / n
的一部分。您应该能够在幻灯片16的公式中填写示例并进行处理。
ɑ
为:
Chicago Pizza cheese cheese
Chicago Pizza cheese supreme
Chicago Pizza supreme cheese
Chicago Pizza supreme supreme
Dominos cheese cheese
Dominos cheese supreme
β
:
cheese cheese
cheese supreme
supreme cheese
supreme supreme
ɑ / β
的结果是:
Chicago Pizza
Dominos
不属于此,因为它错过了(supreme cheese)
和(supreme supreme)
。
尝试使用条件而不是交叉进行连接。条件将确保您正确匹配记录(如果它们在两个关系中,则仅包括它们),而不是将第一个关系中的每个记录与第二个关系中的每个记录匹配。
这是另一个答案的注释。我的大脑受伤了,所以我尝试了之前发布的简洁而完整的答案并且有效。但那仅仅是“给人一条鱼”,所以我不得不看看背后是什么。
这里是ChrisChen3121的2014年1月22日解决方案,仅对括号,注释和换行符进行更改。大多数括号与它们的匹配垂直排列。希望这让事情变得容易看到。遵循美学上重新编写的代码,在尝试可视化/概念化解决方案时产生了中间关系。
长话短说:
- 找目标比萨饼;
- 与\交叉,建立一个幻想超级集合列表,好像所有的比萨饼店服务说馅饼;
- 从那里收到所有“实际服务”的馅饼,以创建一个“缺少这些”的名单;
- 最后,从“现实”的[副本]中,减去“缺失”和......就是这样。
\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)
)
)
//“超过30个”,目标馅饼(由30岁以上的人吃掉)
cheese
supreme
//超级套装所有比萨饼组合所有目标(“超过30个”)//注意:有些组合与现实不符。
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
//从幻想的“超级套装”中减去“实际”之后的差异(剩下的)。然后,这表示什么是MISSING或,“这些披萨店不提供所需的披萨”
Dominos | supreme
Little Caesars | supreme
Straw Hat | supreme
基于所有比萨饼店至少提供一种比萨饼的假设,我们会发现30岁以上的人不会吃的比萨饼将被所有比萨饼店出售,除了那些独家销售比萨饼的比萨饼。 30做EAT。它有帮助吗?
这是http://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html到MySQL的转换
mysql>create table parts (pid integer); mysql>create table catalog (sid integer,pid integer); mysql>insert into parts values ( 1), (2), (3), (4), (5); mysql>insert into catalog values (10,1); mysql>select * from 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; +------+------+ | 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); +------+------+ | 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)); +------+ | sid | +------+ | 1 | +------+
我根据wiki想出了下面的内容。
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)))))
\project_{pizzeria}Serves
\diff
\project_{pizzeria}((\project_{pizza}(\select_{age < 30}Person\joinEats)
\diff\project_{pizza}(\select_{age > 30}Person\joinEats))\joinServes);
========================================================================
就这么简单。我做了什么?在第二部分,我发现披萨列表中不包括被30岁以上的人吃掉的比萨饼。
我加入了比萨饼店,以便看看哪些比萨饼店也为年轻人制作披萨。
我与最初的比萨饼店名单不同,唯一一个为30岁以上的人制作比萨饼的是芝加哥比萨饼。