Как найти все пиццерии, которые подают каждую пиццу, которую съели люди старше 30 лет?
-
27-10-2019 - |
Вопрос
Я следую за курсом базы данных в Стэнфорде, и есть вопрос, где у нас Найдите все пиццерии, которые подают каждую пиццу, которую съели люди старше 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
Форумы вопросов и ответов говорят нам об использовании подразделения и укажите нам на несколько презентаций. Хотя я понимаю, каким будет результат действия, я не очень понимаю, как перевести формулу в синтаксис реляционной алгебры.
Может ли кто -нибудь объяснить мне, что мне не хватает, надеюсь, не давая решению?
Решение
Решением является оператор Join Divhttp://en.wikipedia.org/wiki/relational_algebra#division_.28.c3.b7.29
Видетьhttp://oracletoday.blogspot.com/2008/04/relational-algebra-division-in-sql.html
Другие советы
Определенно это концепция оператора дивизии в реляционной алгебре.
Но я попробовал этот курс. Синтаксис реляционной алгебры 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 обратите внимание, что 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)
.
Попробуйте сделать соединение, используя условия, а не крест. Условия будут уверены, что вы правильно сопоставляете записи (вы включаете их только в том случае, если они находятся в обеих отношениях), а не сопоставляете каждую запись в первой связи с каждой записью во втором соотношении.
Это аннотация другого ответа. Мой мозг болел, и поэтому я попробовал краткий и полный ответ, опубликованный ранее, и это сработало. Но это просто «дать человеку рыбу», и я должен был увидеть, что за этим было.
Здесь находится решение Chrischen3121 от 22 января '14 с изменениями только в скобку, комментариях и разрывах строк. Большая часть скобок выходит вертикально с их матчем. Надеюсь, что это облегчает все для того, чтобы увидеть. Следуя эстетически переписываемому коду, существуют промежуточные отношения, созданные в попытке визуализировать/концептуализировать решение.
Короче говоря:
-Пополнительная целевая пицца;
-С Крестом, создайте фэнтезийный список супер-настройки, как будто все пиццерии подали сказанные пироги;
-Отключите оттуда все «фактически сервирующие» пироги, чтобы создать список «упущенных»;
-Финко, из [свежей копии] «реальности», вычтите «пропавшего без вести» и ... это все.
\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)
)
)
// «более 30pies», целевые пироги (те, кто съел 30+ лет)
cheese
supreme
// Super Set из всех пиццерий в сочетании со всеми Target («более 30pies») // Примечание. Некоторые комбинации не соответствуют реальности.
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 | +------+
Я выяснил ниже на основе вики.
R: = project_ {pizzeria, pizza} ( select_ {age> 30} (человек join eats join обслуживает)))
S: = project_ {pizza} ( select_ {age> 30} (человек join eats join обслуживает))
Окончательное решение:
project_ {pizzeria} ( project_ {pizzeria, pizza} ( select_ {age> 30} (человек join eats join обслуживает))))))
diff
( project_ {pizzeria} (( project_ {pizzeria} ( project_ {pizzeria, pizza} ( select_ {age> 30} (человек join eats join serves)) cross project_ {pizza} ( select_ {Age> 30} (Person Join eats join обслуживает)) diff ( project_ {pizzeria, pizza} ( select_ {age> 30} (человек join eats join обслуживает)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
Привет, я нашел решение без разделительного оператора:
\project_{pizzeria}Serves
\diff
\project_{pizzeria}((\project_{pizza}(\select_{age < 30}Person\joinEats)
\diff\project_{pizza}(\select_{age > 30}Person\joinEats))\joinServes);
========================================================================
Это так просто. Что я сделал? Во второй части я нашел список пиццы, в котором не было пиццу, которую съели более 30.
Я присоединился к ним с пиццериями, чтобы увидеть, какие пиццерии делают пиццу также для молодых людей.
Я отличался от первоначального списка пиццерий, и единственная, которая делает пиццу для тех, кто выше 30, - это чикагская пицца.