2015-02-04 3 views
1

У меня есть эта схема:Проектирование баз данных Реляционная алгебра запрос

Suppliers(sid: integer, sname: string, address: string) 
Parts(pid: integer, pname: string, color: string) 
Catalog(sid: integer, pid: integer, cost: real) 

И эту задачу:

Find the sids of suppliers who supply every part. 

То, что я не понимаю, почему в этом решении мы не работаем с отрицанием , У меня возникло соблазн поставить C1.pid <> P.pid вместо C1.pid = P.pid в конце. Может кто-нибудь объяснить?

SELECT C.sid 
FROM Catalog C 
WHERE NOT EXISTS (SELECT P.pid 
FROM Parts P 
WHERE NOT EXISTS (SELECT C1.sid 
FROM Catalog C1 
WHERE C1.sid = C.sid 
AND C1.pid = P.pid)) 

ответ

2

Предположим, у вас есть 2 части и 1 поставщик. Поставщик имеет обе части. Если вы присоединитесь к <>, ваш самый внутренний подзапрос получит две строки назад: один для записи в каталоге для части №1 (потому что Part #1 <> Part #2 - это правда); и один для входа в каталог для части № 2 (аналогично).

Ваше рассуждение не полностью выключен, но способ сделать это не использовать неравенство, а использовать внешнее соединение и испытание для отсутствующей записи на «внешней» стол:

SELECT c.sid 
FROM catalog c 
WHERE NOT EXISTS 
      (SELECT c1.sid 
      FROM catalog c1 LEFT JOIN parts p ON c1.pid = p.pid 
      WHERE c.sid = c1.sid AND p.pid IS NULL) 

Лично я считаю, что вложенный not exists будет немного запутанным и излишне сложным. Я бы с большей вероятностью разрешил эту проблему, используя count:

SELECT c.sid 
FROM  catalog c 
GROUP BY c.sid 
HAVING COUNT (DISTINCT c.pid) = (SELECT COUNT (*) FROM parts) 
+0

Да, вы правы, это проще: D –