如何找到所有为 30 岁以上的人吃的比萨饼提供服务的比萨店?

Posted

技术标签:

【中文标题】如何找到所有为 30 岁以上的人吃的比萨饼提供服务的比萨店?【英文标题】:How to find all pizzerias that serve every pizza eaten by people over 30? 【发布时间】:2011-10-19 13:01:07 【问题描述】:

我正在关注斯坦福数据库课程,有一个问题是我们仅使用关系代数查找所有为 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. 虽然我知道操作的结果是什么,但我真的不明白如何将公式转换为关系代数语法。

谁能解释我缺少什么,希望不要直接给出解决方案?

【问题讨论】:

这个问题经常被问到。请参阅***.com/questions/7731877/…您所询问的详细信息在我对该问题的回答中。 我不知道,但你的回答不是很有帮助。我在将自己的数据转换为部门查询时遇到了问题,因此将我发送到另一个完全不相关的示例并没有帮助我解决它 【参考方案1】:

这肯定是关系代数中除法算子的概念。

但我尝试过那门课程。 RA 关系代数语法不支持开发运算符。所以我改用了 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)
)

【讨论】:

【参考方案2】:

    在幻灯片 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)

【讨论】:

如果那是 alpha,那么 alpha 的 A-B 投影是什么(见幻灯片 18)?我仍然在将这个公式转化为具体的东西时遇到一些困难 @IvoFlipse:幻灯片上写着Compute all possible attribute pairings 表示该投影。 请让您的帖子独立。这篇文章本身没有任何意义。【参考方案3】:

解决方案是连接 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

【讨论】:

哇哦,终于有一个甚至使用关系代数的例子了!【参考方案4】:

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

【讨论】:

【参考方案5】:

这是另一个答案的注释。我的大脑很痛,所以我尝试了之前发布的简洁而完整的答案,它奏效了。但这只是“给男人一条鱼”,所以我必须看看背后是什么。

这里是 ChrisChen3121 的 2014 年 1 月 22 日解决方案,仅对括号、cmets 和换行符进行了更改。大多数括号与它们的匹配垂直排列。希望这能让事情变得容易看到。在美学上重新编写的代码之后,会产生中间关系以尝试将解决方案可视化/概念化。

长话短说:

--寻找目标披萨;

--使用\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

【讨论】:

【参考方案6】:

基于所有比萨店都至少提供一种比萨饼的假设,我们会发现 30 岁以上的人不吃的比萨饼组将被所有比萨店出售,除了专门销售比萨饼的比萨饼店30岁以上的人吃。有帮助吗?

【讨论】:

不,不是真的,因为我没有掌握如何在关系代数中表达这一点。但幸运的是,其他答案帮助我解决了它:-)【参考方案7】:

这里是http://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html的转换 到 mysql

mysql>创建表部分(pid整数); mysql>创建表目录(sid整数,pid整数); mysql>insert into parts values (1), (2), (3), (4), (5); mysql>插入目录值(10,1); mysql>从目录中选择*; +------+------+ |席位 |进程号 | +------+------+ | 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; +------+------+ |席位 |进程号 | +------+------+ | 10 | 1 | | 10 | 2 | | 10 | 3 | | 10 | 4 | | 10 | 5 | | 1 | 1 | | 1 | 2 | | 1 | 3 | | 1 | 4 | | 1 | 5 | +------+------+ mysql>选择 * 从 (select distinct sid,pid from (select sid from catalog) a ,parts) b where 不存在(从目录 c 中选择 1,其中 b.sid = c.sid 和 b.pid = c.pid); +------+------+ |席位 |进程号 | +------+------+ | 10 | 2 | | 10 | 3 | | 10 | 4 | | 10 | 5 | +------+------+ mysql>从目录c1中选择不同的sid 不存在的地方( 从 p 部分中选择 null 其中不存在(从 pid=p.pid 和 c1.sid=sid 的目录中选择 null)); +------+ |席位 | +------+ | 1 | +------+

【讨论】:

【参考方案8】:

我根据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)))

\差异

( \project_比萨店 ( ( \project_pizzeria (\project_pizzeria, Pizza (\select_age>30 (Person \join Eats \join Serves))) \叉 \project_pizza (\select_age>30 (Person \join Eats \join Serves)) ) \差异 ( \project_pizzeria, Pizza (\select_age>30 (Person \join Eats \join Serves)) ) ) )

【讨论】:

【参考方案9】:

您好,我找到了一个无需除法运算符的解决方案:

\project_pizzeriaServes
\diff
\project_pizzeria((\project_pizza(\select_age < 30Person\joinEats)
\diff\project_pizza(\select_age > 30Person\joinEats))\joinServes);

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

就这么简单。 我做了什么? 在第二部分中,我发现披萨清单不包括 30 岁以上的人吃的披萨。

我加入了比萨店,以了解哪些比萨店也为年轻人制作比萨饼。

我与最初的披萨店列表不同,唯一一家为 30 岁以上的人制作披萨的是芝加哥披萨。

【讨论】:

以上是关于如何找到所有为 30 岁以上的人吃的比萨饼提供服务的比萨店?的主要内容,如果未能解决你的问题,请参考以下文章

一个即将30岁程序员的自诉,内卷环境下迷惘的大龄程序员该如何破局?

猿团专访|村支书的创业梦:让吃的人健康,让养的人小康

一个即将30岁Android程序员的自诉,在内卷的大环境之下迷惘的大龄程序员该如何破局?

深度 | 30 岁以上的 .NET 程序员,都去了哪儿?

34岁程序员面试被拒,HR:只招30岁以下,活好能加班工资又少的人

想清楚自己创业的目的(一定要提供全新的服务才有意义,24岁成功和42岁成功的区别也没有那么大)