SQL: использование Not Exists с вложенным запросом

У меня возникли проблемы с пониманием того, что этот запрос работает. Предполагается вернуть имя клиентов, заказавших ВСЕ товары.

R относится к таблице заказов товаров, сделанных клиентами, которая содержит идентификатор клиента (cid) и идентификатор товара (iid).

I относится к таблице элементов, которые можно заказать, которая содержит идентификатор элемента.

C — это таблица клиентов с идентификатором клиента.

SELECT cname
FROM Customer C
WHERE NOT EXISTS
(  (SELECT I.iid
       FROM Item I)
    EXCEPT
   (SELECT R.iid
      FROM Order R
      WHERE R.cid=C.cid))

Насколько я понимаю, нижний вложенный запрос с SELECT R.iid получает все товары, заказанные любым покупателем.

Затем вложенный запрос выше EXCEPT с SELECT I.iid находит все элементы, которые не были заказаны ранее, путем минусования с помощью приведенного ниже запроса.

Если он вложен, какой оператор НЕ СУЩЕСТВУЕТ? Это R.cid = C.cid из-за ОТ Заказчика C? . Я не уверен, как я получу свой конечный результат. Спасибо за любую помощь.


person roverred    schedule 27.02.2013    source источник
comment
Предполагается, что будут возвращены имена клиентов, заказавших ВСЕ товары. Да   -  person Conrad Frix    schedule 28.02.2013
comment
Здесь сработает двойной трюк NOT EXISTS.   -  person wildplasser    schedule 28.02.2013
comment
Вы должны были задать вопрос, не говоря, что он должен делать :)   -  person Kaf    schedule 28.02.2013


Ответы (2)


SELECT I.iid FROM Item I означает "ID всех элементов".

SELECT R.iid FROM Order R WHERE R.cid=C.cid означает "идентификаторы всех товаров, которые клиент C когда-либо заказывал" (где C определяется содержащим запрос).

В общем случае query1 EXCEPT query2 означает "все строки, возвращенные query1 и не возвращенные query2". В вашем конкретном случае (SELECT I.iid FROM Item I) EXCEPT (SELECT R.iid FROM Order R WHERE R.cid=C.cid) означает "идентификаторы всех товаров, которые клиент C никогда не заказывал".

Внутри выражения NOT EXISTS (subquery) все, что действительно имеет значение, это возвращает ли subquery какие-либо строки (в этом случае оно «существует») или нет. Таким образом, (SELECT I.iid FROM Item I) EXCEPT (SELECT R.iid FROM Order R WHERE R.cid=C.cid) существует, если есть товар, который клиент C никогда не заказывал, и не существует, если нет такого товара. .

Таким образом, запрос в целом находит имена клиентов, заказавших каждый отдельный товар.

person ruakh    schedule 27.02.2013

Сломай. Начиная назад/с самого внутреннего запроса:

Это возвращает список идентификаторов товаров, заказанных покупателем. (Я предполагаю, что iid означает идентификатор элемента и является fk в R)

SELECT R.iid FROM Order R WHERE R.cid=C.cid

Это возвращает список идентификаторов товаров (обычно), кроме тех, которые уже заказаны покупателем.

SELECT I.iid FROM Item I EXCEPT...

Наконец, это возвращает список клиентов, которые НЕ заказали один из элементов в списке.

SELECT cname FROM Customer C Where NOT EXISTS...

Таким образом, вы ищете клиентов, которые заказали хотя бы одно из всего.

person Chains    schedule 27.02.2013