Перечислите поставщиков без продуктов (AdventureWorks)
Мне задали вопрос, используя AdventureWorks, чтобы перечислить всех поставщиков без продуктов. Когда я запускаю оператор SELECT, ничего не возвращается. Что я делаю неправильно? (Ответ может быть сделан только с помощью соединений и союзов - без подзапросов)
SELECT DISTINCT pv.Name AS 'Vendors'
FROM Purchasing.Vendor pv
INNER JOIN Purchasing.ProductVendor ppv
ON pv.BusinessEntityID = ppv.BusinessEntityID
INNER JOIN Production.Product pp
ON pp.ProductID = ppv.ProductID
WHERE pp.ProductID != ppv.ProductID;
3 ответа
Решение
Вы смотрите на слишком много таблиц, у всех ProductVendors есть Продукты. Не у всех поставщиков есть ProductVendors.
Оттуда вы можете просто использовать LEFT JOIN
и искать нулевые записи.
SELECT DISTINCT v.Name
FROM Purchasing.Vendor v
LEFT JOIN Purchasing.ProductVendor pv ON pv.BusinessEntityID = v.BusinessEntityID
WHERE pv.BusinessEntityID IS NULL
- Используйте левое соединение, чтобы включить случаи, когда нет продукта для "продавца". Внутреннее объединение будет учитывать только те случаи, когда для поставщика существует идентификатор продукта.
- Теперь сделайте группировку по "Продавцу" и посчитайте количество товаров, используя
COUNT()
функция. - Наконец, отфильтруйте тех поставщиков, у которых счетчик равен нулю, используя
HAVING
пункт
Попробуйте следующее:
SELECT pv.Name AS 'Vendors',
Count(pp.ProductID) AS count_products
FROM Purchasing.Vendor pv
LEFT JOIN Purchasing.ProductVendor ppv
ON pv.BusinessEntityID = ppv.BusinessEntityID
LEFT JOIN Production.Product pp
ON pp.ProductID = ppv.ProductID
GROUP BY pv.Name
HAVING count_products = 0;
SELECT DISTINCT pv.Name AS 'Vendors'
FROM Purchasing.Vendor pv
INNER JOIN Purchasing.ProductVendor ppv
ON pv.BusinessEntityID = ppv.BusinessEntityID
where not exists (SELECT 1 Production.Product pp Where pp.ProductID = ppv.ProductID)
Вернуть всех продавцов, у которых нет продуктов