如何找到为 30 岁以上人群提供所有披萨的所有披萨店?

发布于 2024-12-11 07:43:27 字数 1000 浏览 0 评论 0原文

我正在学习斯坦福数据库课程,有一个问题是,我们仅使用关系代数查找为 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 岁以上的人吃哪些披萨,并制作它们的叉积,这样我就可以检查哪家披萨店同时拥有这两种披萨。

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

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

问答论坛告诉我们使用除法,并为我们提供了几个演示文稿。< /a> 虽然我知道该操作的结果是什么,但我并不真正理解如何将公式转换为关系代数语法。

谁能解释一下我所缺少的东西,希望不要直接给出解决方案?

I'm following the Stanford Database course and there's a question where we have Find all pizzerias that serve every pizza eaten by people over 30 using Relational Algebra only.

The problem consist of 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

I know how to find which pizza's people over 30 eat and make a cross-product of them, so I could check which pizzeria has both.

I can make a list of all the pizzeria's that serve those pizza's, but I have no idea how to remove any pizzeria that only have one combination (like Dominos).

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

The Q&A forums tell us to use division and point us to several presentations. While I get what the result of the action would be, I don't really understand how to translate the formula's into relational algebra syntax.

Could anyone explain me what I'm missing, hopefully without giving the solution outright?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

北渚 2024-12-18 07:43:27

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

但我尝试过那门课程。 RA 关系代数语法不支持 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)
)

Definitely this is the concept of division operator in relational algebra.

But I tried on that course. The RA Relational Algebra Syntax doesn't support dev operator. So I used diff and cross instead. Here is my solution:

\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)
)
删除→记忆 2024-12-18 07:43:27
  1. 在幻灯片 6 上,请注意 n 为 (3 1 7)

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

  3. 如果o也有(12 3)(12 1)但没有(12 7), 12 不会成为 o / n 的一部分。

您应该能够在幻灯片 16 的公式中填写一个示例并计算出来。

  1. 就您而言,我们将 ɑ 视为:

    芝加哥披萨奶酪奶酪
    芝加哥披萨奶酪至尊
    芝加哥披萨 顶级奶酪
    芝加哥披萨至尊至尊
    多米诺骨牌奶酪 奶酪
    多米诺骨牌奶酪至尊
    
  2. 然后我们将 β 设为:

    奶酪奶酪
    至尊奶酪
    至尊奶酪
    至尊 至尊
    
  3. ɑ / β的结果为:

    芝加哥披萨
    

Dominos 不属于此,因为它错过了 (至尊奶酪) 和 (至高无上)

  1. On slide 6, note that n is (3 1 7).

  2. On the next slide, o / n results in (4 8).

  3. If o would also have (12 3) and (12 1) but not (12 7), 12 would not be part of o / n.

You should be able to fill in an example in the formula on Slide 16 and work it out.

  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
    

Dominos is not part of this because it misses (supreme cheese) and (supreme supreme).

玉环 2024-12-18 07:43:27

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

Try doing a join using conditions rather than a cross. The conditions would be sure that you match up the records correctly (you only include them if they are in both relations) rather than matching every record in the first relation to every record in the second relation.

好倦 2024-12-18 07:43:27

这是ChrisChen3121 的解决方案 仅更改了括号、注释和换行符。大多数括号与其匹配项垂直对齐。在美观地重新编写的代码之后是试图可视化/概念化解决方案而产生的中间关系。

  • 查找“30岁以上披萨”目标列表(30岁以上的人吃的披萨);

  • 使用 \cross,构建所有比萨店与 Over-30-Pizzas 相结合的“Fantasy-Superset”列表,就好像所有比萨店都提供目标 Over-30-Pizzas 一样;

  • 从中减去比萨店实际提供的“实际提供的”列表,以创建“缺少的”列表;

  • 从“实际提供的”内容的[新副本]中减去出现在“缺失内容”中的比萨店。

    // "Actually-Served" list of what pizzerias serve in reality. Results shown below.
    \project_{pizzeria}(Serves)
\diff
    \project_{pizzeria}
        (// "What's-Missing" list. Results shown below.
            (// "Fantasy-Superset" list of all pizzerias combined with Over-30-Pizzas. Results shown below.
             // NOTE: Some combos here do not match reality.
                // all pizzarias
                \project_{pizzeria}(Serves)
            \cross
                // "Over-30-Pizzas" target list (those eaten by 30+-year-olds). Results shown below.
                \project_{pizza}(\project_{name}(\select_{age > 30 }(Person)) \join Eats)
                // What I used instead, it’s equivalent.
                // \project_{pizza}(\select_{age > 30} Person \join Eats)
            )
        \diff
            // "Actually-Served" list of what pizzerias serve in reality. Result shown below.
            \project_{pizzeria,pizza}(Serves)
        )

// “30 岁以上披萨”目标列表(30 岁以上的人吃的披萨)。

cheese 
supreme

// 所有披萨店与 Over-30- 相结合的“Fantasy-Superset”列表比萨饼。
// 注意:某些组合与现实不符。

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

Here is ChrisChen3121’s solution with changes only to parentheses, comments, and line breaks. Most parentheses line up vertically with their match. Following the aesthetically re-written code are the intermediate relations produced in an attempt to visualize/conceptualize the solution.

  • Find the "Over-30-Pizzas" target list (those eaten by 30+-year-olds);

  • With \cross, build a "Fantasy-Superset" list of all pizzerias combined with Over-30-Pizzas, as if all pizzerias served the target Over-30-Pizzas;

  • Subtract out from there the "Actually-Served" list of what pizzerias serve in reality to create a "What's-Missing" list;

  • From [a fresh copy of] what's Actually-Served, subtract out pizzerias appearing in What's-Missing.

    // "Actually-Served" list of what pizzerias serve in reality. Results shown below.
    \project_{pizzeria}(Serves)
\diff
    \project_{pizzeria}
        (// "What's-Missing" list. Results shown below.
            (// "Fantasy-Superset" list of all pizzerias combined with Over-30-Pizzas. Results shown below.
             // NOTE: Some combos here do not match reality.
                // all pizzarias
                \project_{pizzeria}(Serves)
            \cross
                // "Over-30-Pizzas" target list (those eaten by 30+-year-olds). Results shown below.
                \project_{pizza}(\project_{name}(\select_{age > 30 }(Person)) \join Eats)
                // What I used instead, it’s equivalent.
                // \project_{pizza}(\select_{age > 30} Person \join Eats)
            )
        \diff
            // "Actually-Served" list of what pizzerias serve in reality. Result shown below.
            \project_{pizzeria,pizza}(Serves)
        )

// "Over-30-Pizzas" target list (those eaten by 30+-year-olds).

cheese 
supreme

// "Fantasy-Superset" list of all pizzerias combined with Over-30-Pizzas.
// NOTE: some combos do not match reality.

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

// "Actually-Served" list of what pizzerias serve in reality.

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

\\ "What's-Missing" list. Difference (what’s left over) after the Actually-Served is subtracted from the Fantasy-Superset. "These pizzerias do not serve the required pizza listed."

Dominos        | supreme
Little Caesars | supreme
Straw Hat      | supreme
你曾走过我的故事 2024-12-18 07:43:27

以下是 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 |
+------+

Here is the conversion of http://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html
to 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 |
+------+

遗忘曾经 2024-12-18 07:43:27

基于所有比萨饼店至少提供一种比萨饼的假设,我们会发现,30 岁以上的人不吃的那组比萨饼将由所有比萨饼店出售,除了专门出售 30 岁以上的人不吃的比萨饼的比萨饼店外。 30 吃。

Based on the assumption that all pizzerias serve at least one type of pizza, we will find that the group of pizzas that people over 30 do NOT EAT will be sold by all the pizzerias EXCEPT the one(s) who sell exclusively pizzas which people over 30 do EAT.

神爱温柔 2024-12-18 07:43:27
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))
            )
        )
    )
R:=
\project_{pizzeria, pizza} (\select_{age>30} (Person \join Eats \join Serves))

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

Final solution:

    \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))
            )
        )
    )
岁吢 2024-12-18 07:43:27

没有除法运算符的解决方案:

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

在第二部分中,我发现了一个披萨列表,其中不包括 30 岁以上的人吃的披萨。

我将它们与披萨店一起加入,以便看看哪些披萨店也为年轻人制作披萨。

我从原来的披萨店名单中减去了它,唯一一家为 30 岁以上的人制作披萨的就是芝加哥披萨店。

A solution without the division operator:

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

In the second part I found a pizza list that did not include pizzas that are eaten by those above 30.

I joined them with pizzerias in order to see which pizzerias make pizza for younger people also.

I subtracted that from the original list of pizzerias and the only one that makes pizza for those above 30 is Chicago Pizza.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文