Как найти все пиццерии, которые подают каждую пиццу, которую едят люди старше 30 лет? - PullRequest
16 голосов
/ 19 октября 2011

Я изучаю курс базы данных Stanford Database, и у нас есть вопрос, где у нас есть Найдите все пиццерии, которые подают каждую пиццу, которую едят люди старше 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

Форумы Q & A советуют нам использовать деление и указывают на несколько презентаций. Хотя я и получаю, каков будет результат действия, я не совсем понимаю, как перевести формулу в синтаксис реляционной алгебры.

Может ли кто-нибудь объяснить мне, что мне не хватает, надеюсь, не дав прямого решения?

Ответы [ 9 ]

8 голосов
/ 22 января 2014

Определенно, это понятие оператора деления в реляционной алгебре.

Но я попробовал этот курс. Синтаксис реляционной алгебры 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)
)
6 голосов
/ 28 октября 2011
6 голосов
/ 19 октября 2011
  1. На слайде 6 обратите внимание, что n равно (3 1 7).

  2. На следующем слайде o / n приводит к (4 8).

  3. Если o также будет иметь (12 3) и (12 1), но не (12 7), 12 не будет частью o / n.

Вы должны быть в состоянии заполнить пример в формуле на слайде 16 и обработать его.

  1. В вашем случае мы принимаем ɑ:

    Chicago Pizza   cheese  cheese
    Chicago Pizza   cheese  supreme
    Chicago Pizza   supreme cheese
    Chicago Pizza   supreme supreme
    Dominos         cheese  cheese
    Dominos         cheese  supreme
    
  2. Тогда мы берем β:

    cheese cheese
    cheese supreme
    supreme cheese
    supreme supreme
    
  3. Результат ɑ / β будет тогда:

    Chicago Pizza
    

Dominos не является частью этого, потому что он пропускает (supreme cheese) и (supreme supreme).

3 голосов
/ 28 октября 2011

Попробуйте сделать соединение, используя условия, а не крест.Условия будут гарантировать, что вы правильно сопоставляете записи (вы включаете их, только если они находятся в обоих отношениях), а не сопоставляете каждую запись в первом отношении с каждой записью во втором отношении.

2 голосов
/ 19 сентября 2016

Это аннотация другого ответа.Мой мозг болел, и поэтому я попробовал краткий и полный ответ, опубликованный ранее, и это сработало.Но это просто «дать человеку рыбу», и поэтому мне пришлось посмотреть, что за этим стоит.

Вот тогда решение ChrisChen3121 от 22 января 141 года с изменениями только в скобках, комментариях и переносах строк.Большинство круглых скобок выстраиваются вертикально вместе с их соответствием.Надеюсь, что это делает вещи легко увидеть.Следуя эстетически переписанному коду, существуют промежуточные отношения, возникающие в попытке визуализировать / концептуализировать решение.

Короче говоря:

- Найти целевую пиццу;

- С помощью \ 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)
    )
)

// «более 30 пирогов», целевые пироги (съеденные более 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
1 голос
/ 22 марта 2013

Я разобрался ниже на основе вики.

Р: = \ project_ {пиццерия, пицца} (\ select_ {age> 30} (человек \ присоединиться к еде \ присоединиться к серверу))

S: = \ project_ {pizza} (\ select_ {age> 30} (человек \ присоединиться к еде \ присоединиться к серверу))

Окончательное решение:

\ project_ {pizzeria} (\ project_ {пиццерия, пицца} (\ select_ {age> 30} (Person \ join Eats \ join Serves)))

\ Diff

( \ project_ {пиццерии} ( ( \ project_ {пиццерия} (\ project_ {пиццерия, пицца} (\ select_ {age> 30} (человек \ присоединиться к еде \ присоединиться к подаче))) \пересекать \ project_ {pizza} (\ select_ {age> 30} (Person \ join Eats \ join Serves)) ) \ дифф ( \ project_ {пиццерия, пицца} (\ select_ {age> 30} (Person \ join Eats \ join Serves)) ) ) )

1 голос
/ 31 января 2013

Вот преобразование 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 |
+------+

1 голос
/ 09 ноября 2011

Исходя из предположения, что все пиццерии обслуживают по крайней мере один тип пиццы, мы обнаружим, что группа пицц, которые НЕ ЕДЯТ старше 30 лет, будет продана всеми пиццериями, КРОМЕ ТОГО, ЧТО (ые) продают исключительно пиццу которые люди старше 30 едят. Помогло ли это?

0 голосов
/ 12 мая 2018

Привет, я нашел решение без оператора деления:

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

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

это так просто. Что я сделал? во второй части я нашел список пиццы, в котором не было пиццы, которую едят те, кто старше 30.

Я присоединился к ним с пиццериями, чтобы посмотреть, какие пиццерии делают пиццу для молодых людей.

Я отличался от оригинального списка пиццерий, и только пицца для тех, кто старше 30 лет, - это Chicago Pizza.

...