我正在关注斯坦福数据库课程,并且我们有一个问题仅使用关系代数查找为超过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岁以上的人吃了它们并制作了它们的交叉产品,所以我可以检查哪个披萨店都有。
我可以列出所有披萨店的披萨,但我不知道如何去除任何只有一个组合的披萨店(如Dominos)。
Chicago Pizza cheese cheese
Chicago Pizza cheese supreme
Chicago Pizza supreme cheese
Chicago Pizza supreme supreme
Dominos cheese cheese
Dominos cheese supreme
Q& A论坛告诉我们使用除法和point us to several presentations.虽然我得到了行动的结果,但我真的不明白如何将公式转换为关系代数语法。
任何人都可以向我解释我所缺少的东西,希望不会直接给出解决方案吗?
答案 0 :(得分:8)
这绝对是关系代数中除法运算符的概念。
但我试过这个课程。 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)
)
答案 1 :(得分:6)
在幻灯片6中,请注意n是(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)
。
答案 2 :(得分:6)
解决方案是join div运算符 http://en.wikipedia.org/wiki/Relational_algebra#Division_.28.C3.B7.29
请参阅 http://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html
答案 3 :(得分:3)
尝试使用条件而不是交叉进行连接。条件将确保您正确匹配记录(如果它们在两个关系中,则仅包括它们),而不是将第一个关系中的每个记录与第二个关系中的每个记录匹配。
答案 4 :(得分:2)
这是另一个答案的注释。我的大脑受伤了,所以我尝试了之前发布的简洁而完整的答案并且有效。但那仅仅是“给人一条鱼”,所以我不得不看看背后是什么。
然后是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
//超级套装所有比萨饼与所有目标相结合(“超过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
答案 5 :(得分:1)
基于所有比萨饼店至少提供一种比萨饼的假设,我们会发现30岁以上的人不会吃的比萨饼将被所有的比萨饼店出售,除了独家销售比萨饼的比萨饼之外30岁以上的人做EAT。它有帮助吗?
答案 6 :(得分:1)
以下是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 | +------+
答案 7 :(得分: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_ {比萨饼} ( ( \ project_ {pizzeria}(\ project_ {pizzeria,pizza}(\ select_ {age> 30}(Person \ join Eats \ join Serves))) \交叉 \ project_ {pizza}(\ select_ {age> 30}(Person \ join Eats \ join Serves)) ) \ DIFF ( \ project_ {pizzeria,pizza}(\ select_ {age> 30}(Person \ join Eats \ join Serves)) ) ) )
答案 8 :(得分: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岁以上的人制作披萨的是芝加哥比萨饼。