Мне нужно ВЫБРАТЬ из таблицы на основе атрибутов, отсутствующих в другой таблице

У меня есть следующие таблицы:

   VENDOR:          PRODUCT:           ITEM:             STORE:
-  VENDOR_ID     -  PRODUCT_ID      -  ITEM_ID        -  STORE_ID
-  VENDOR_NAME   -  PRODUCT_DESC    -  STORE_ID       -  STORE_NAME
                 -  VENDOR_ID       -  PRODUCT_ID     -  STORE_LOCATION
                                    -  ITEM_PRICE

Таблица ITEM, по сути, является инвентаризацией магазинов, в которой указано, какие товары есть в наличии в каждом магазине. Я хочу составить список всех продавцов, которые не поставляют товары ни в один из магазинов в базе данных.

Это то, что у меня есть до сих пор:

SELECT DISTINCT VENDOR.VENDOR_NAME AS VENDORNAME
FROM VENDOR, PRODUCT, ITEM, STORE
WHERE NOT VENDOR.VENDOR_ID = PRODUCT.VENDOR_ID
AND NOT PRODUCT.PRODUCT_ID = ITEM.PRODUCT_ID
AND NOT ITEM.STORE_ID = STORE.STORE_ID;

Прямо сейчас он возвращает все имена поставщиков. У вас есть идеи, как заставить возвращать только тех продавцов, товаров которых нет ни в одном из магазинов? Спасибо.


person LaneWalker    schedule 21.10.2013    source источник
comment
Описание вашей задачи не ясно. Вы можете опубликовать образец данных и ожидаемый результат. Также укажите, какую РСУБД (SQL разновидность) вы используете.   -  person PM 77-1    schedule 21.10.2013


Ответы (2)


Поскольку товар показывает, какие продукты есть в каждом магазине для каждого поставщика, если продукт отсутствует в таблице товаров, то это тот, который вам нужен. Левое соединение оставит эти значения нулевыми. Просто проверьте те элементы, которые являются нулевыми. Так:

select *
from vendor v
join product p on v.vendor_id = p.product_id
left join item i on p.product_id = i.product_id
where i.product_id is null

OR

Найдите все товары, которых нет в таблице товаров. Это игнорирует таблицу поставщиков:

select *
from product p
where product_id not in (select product_id from item)

Теперь найдите этих продавцов

select * 
from vendor
where vendor_id in
(
   select vendor_id 
   from product p
   where product_id not in (select product_id from item)
)

Оба этих ответа логически одинаковы, первый использует соединения, второй - подзапросы.

person Hogan    schedule 21.10.2013

Пожалуйста, попробуйте это:

SELECT MAX(v.VENDOR_NAME) AS VENDORNAME
FROM VENDOR v
LEFT JOIN PRODUCT p ON v.endor_id = p_vendor_id
LEFT JOIN ITEM i ON p_product_id = i.product_id
GROUP BY v.vendor_id
HAVING COUNT(i.item_id) = 0;

STORE таблица для такого запроса не нужна.

person PM 77-1    schedule 21.10.2013
comment
хм, а вы уверены насчет левого соединения с продуктом? Я ожидаю, что это будет внутреннее соединение. - person Hogan; 21.10.2013
comment
@Hogan - Разве внутреннее соединение не отфильтровало бы всех поставщиков, у которых нет продуктов? - person PM 77-1; 21.10.2013
comment
Правда, это вопрос требований, я полагал, что ОП не будет заинтересована в этой группе ... но ОП может быть, это неясно. - person Hogan; 21.10.2013