Как найти все пиццерии, которые обслуживают каждую пиццу, съеденную людьми старше 30 лет?
Я следую курсу базы данных Стэнфорда, и есть вопрос, где у нас есть найти все пиццерии, которые обслуживают каждую пиццу, съеденную людьми старше 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
форумы Q&A говорят нам использовать разделение и укажите нам несколько презентаций. хотя я получаю результат действия, я действительно не понимаю, как перевести формулу в синтаксис реляционной алгебры.
может ли кто-нибудь объяснить мне, что мне не хватает, надеюсь, не давая решения откровенная?
9 ответов
решением является оператор 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
на слайде 6 Обратите внимание, что n -
(3 1 7)
.на следующем слайде,
o / n
результаты(4 8)
.если
o
также(12 3)
и(12 1)
а не(12 7)
, 12 не будет частьюo / n
.
вы должны иметь возможность заполнить пример в формуле на слайде 16 и разработать его.
-
в вашем случае, мы берем
ɑ
to быть: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)
.
определенно это понятие оператора деления в реляционной алгебре.
но я пробовал этот курс. Синтаксис реляционной алгебры 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)
)
попробуйте выполнить соединение, используя условия, а не крест. Условия будут уверены, что вы правильно сопоставляете записи (вы включаете их, только если они находятся в обоих отношениях), а не сопоставляете каждую запись в первом отношении с каждой записью во втором отношении.
это аннотация другого ответа. Мой мозг болел, и поэтому я попробовал краткий и полный ответ, опубликованный ранее, и это сработало. Но это просто "дать человеку рыбу", и поэтому я должен был увидеть, что за этим стоит.
вот тогда решение Chrischen3121 от 22 января ' 14 с изменениями только в скобках, комментариях и разрывах строк. Большинство скобок выстраиваются вертикально с их совпадением. Надеюсь, это облегчит обзор. Следование эстетически переписанному коду, существуют промежуточные отношения, созданные в попытке визуализировать / концептуализировать решение.
короче:
--найти целевые пиццы;
--С \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
// супер-набор всех пиццерий в сочетании со всеми target ("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
исходя из предположения, что все пиццерии обслуживают по крайней мере один тип пиццы, мы обнаружим, что группа пицц, которые люди старше 30 лет не едят, будет продаваться всеми пиццериями, кроме одного(ов), которые продают исключительно пиццу, которую люди старше 30 лет едят. Это помогло?
вот преобразование 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_{пиццерия, Пицца} (\select_{возраст>30} (человек \присоединиться ест \присоединиться служит))
S:= \project_{pizza} (\select_{age>30} (Person \join Eats \join Serves))
окончательное решение:
\project_{пиццерия} (\project_{пиццерия, Пицца} (\select_{возраст>30} (человек \присоединиться ест \присоединиться обслуживает)))
\diff
( \project_{пиццерия} ( ( \project_{пиццерия} (\project_{пиццерия, пицца} (\select_{возраст>30} (человек \присоединиться ест \присоединиться подают))) \крест \project_{pizza} (\select_{age>30} (Person \join Eats \join Serves)) ) \разность ( \project_{пиццерия, Пицца} (\select_{возраст>30} (человек \присоединиться ест \присоединиться служит)) ) ) )
Привет я нашел решение без деления оператор:
\project_{pizzeria}Serves
\diff
\project_{pizzeria}((\project_{pizza}(\select_{age < 30}Person\joinEats)
\diff\project_{pizza}(\select_{age > 30}Person\joinEats))\joinServes);
========================================================================
- это так просто. Что я сделал? во второй части я нашел список пиццы, который не включал пиццы, которые едят те, кто старше 30.
Я присоединился к ним с пиццериями, чтобы посмотреть, какие пиццерии делают пиццу для молодых людей.
Я отличался от первоначального списка пиццерии и единственный, который делает пиццу для тех, кто старше 30, - это Чикагская пицца.