How to find all pizzerias that serve every pizza eaten by people over 30?

后端 未结 9 1972
被撕碎了的回忆
被撕碎了的回忆 2020-12-29 07:29

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 Re

相关标签:
9条回答
  • 2020-12-29 08:17

    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 |
    +------+
    
    
    0 讨论(0)
  • 2020-12-29 08:18

    This is the annotation of another answer. My brain was hurting and so I tried a concise and complete answer posted earlier and it worked. But that’s merely “giving a man a fish” and so I had to see what was behind it.

    Here then is ChrisChen3121’s Jan 22 ‘14 solution with changes only to parenthesis, comments, and line breaks. Most parenthesis line up vertically with their match. Hopefully that makes things easy to see. Following the aesthetically re-written code, there are the intermediate relations produced in an attempt to visualize/conceptualize the solution.

    Long story short:

    --Find target pizzas;

    --With \cross, build a fantasy super-set list as if all pizzerias served said pies;

    --Subtract out from there, all “Actually-Served” pies to create a “These-Are-Missing” list;

    --Finally, from [a fresh copy of] “reality”, subtract out the “missing” and... that’s about it.

    \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”, target pies (those eaten by 30+ year-olds)

    cheese 
    supreme
    

    // Super-Set of all pizzerias combined with all target ("over30pies") // 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
    

    // Actual, full list of which pizzerias actually serve what

    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
    

    //Difference (what’s left over) after the “Actual” is subtracted from the fantastical “Super-Set”. This then, represents what’s MISSING or, “These pizzeria do not serve the required pizza listed"

    Dominos | supreme
    Little Caesars | supreme
    Straw Hat | supreme
    
    0 讨论(0)
  • 2020-12-29 08:19

    I figured out below based on wiki.

    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)) ) ) )

    0 讨论(0)
提交回复
热议问题