Ответ 1
Решение - это оператор объединения 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
Я слежу за курсом базы данных в Стэнфорде, и есть вопрос, где у нас есть Найти все пиццерии, которые обслуживают каждую пиццу, съеденную людьми старше 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 говорят нам использовать деление и указывают нам на несколько презентаций. Пока я получаю то, что результат действия будет, Я действительно не понимаю, как преобразовать формулу в синтаксис реляционной алгебры.
Может ли кто-нибудь объяснить мне, что мне не хватает, надеюсь, без прямого решения?
Решение - это оператор объединения 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 и выполнить его.
В вашем случае мы берем ɑ
как:
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)
)
Попробуйте выполнить соединение, используя условия, а не крест. Условия были бы уверены, что вы правильно сопоставляете записи (вы включаете их только в том случае, если они находятся в обоих отношениях), а не соответствуют каждой записи в первом отношении к каждой записи во втором отношении.
Это аннотация другого ответа. Моему мозгу было больно, поэтому я попробовал краткий и полный ответ, опубликованный ранее, и это сработало. Но это просто "дает человеку рыбу", и поэтому мне нужно было посмотреть, что стоит за ней.
Вот тогда решение ChrisChen3121s Jan 22 '14 с изменениями только для скобок, комментариев и разрывов строк. Большинство скобок выстраиваются вертикально с их совпадением. Надеюсь, это упростит ситуацию. После эстетически переписанного кода существуют промежуточные отношения, созданные в попытке визуализировать/концептуализировать решение.
Короче говоря:
- Найти целевые пиццы;
- С помощью \cross создайте список супер-установленных фантазий, как если бы все пиццерии обслуживали упомянутые пироги;
- вычитайте оттуда все пироги "на самом деле", чтобы создать список "These-Are-Missing";
- Наконец, из [новой копии] "реальности" вычтите "недостающие" и... вот и все.
\project_{pizzeria}(Serves)// "Actual" list of what pizzerias serve. Results shown below.
\diff
\project_{pizzeria}
(// After the diff, this is a list of "What 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
//Разница (что осталось) после того, как "Фактический" вычитается из фантастического "Супер-набора". Затем это означает, что MISSING или "Эти пиццерии не обслуживают требуемую пиццу"
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_ {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_ {пиццерия, пицца} (\ select_ {age > 30} (Person\join Eats\join Serves))) \пересекать \ project_ {pizza} (\ select_ {age > 30} (Person\join Eats\join Serves)) ) \ дифф ( \ project_ {пиццерия, пицца} (\ select_ {age > 30} (Person\join Eats\join Serves)) ) ) )