#mysql #left-join #relational-database
Вопрос:
У меня есть таблица производителей и продуктов. Я пытаюсь написать 2 запроса: Производители, у которых есть продукты, и производители, у которых их нет.
Строки, возвращаемые из каждого запроса, должны суммироваться с общим количеством строк в таблице производителя, но это не относится к моему коду. Сумма обоих запросов составляет 819, но в таблице производителя всего 766 строк. Откуда берутся дубликаты?
Что я делаю не так со своими объединениями?
PRODUCER TABLE
------ -------- ------ ------
| producerID | producerName |
------ -------- ------ ------
| 123 | Toys R Us |
| 234 | GameStop |
| 345 | Amazon |
------ -------- ------ ------
PRODUCT TABLE
------ -------- ------ -------- ------
| productID | productName | producerID |
------ -------- ------ -------- ------
| 1 | Mega Man | 123 |
| 2 | Lemmings | 234 |
| 3 | Mario Kart | 234 |
------ -------- ------ -------- ------
/*STORES CARRYING Products*/
/*This query returns 169*/
SELECT producerName, pt.producerID, productName
FROM Product pt
INNER JOIN Producer pd ON pt.producerID = pd.producerID
/*STORES NOT CARRYING Products*/
/*This query returns 650 */
SELECT producerName, pt.producerID, productName
FROM Producer pd
LEFT OUTER JOIN Product pt ON pt.producerID = pd.producerID
WHERE pt.producerID IS NULL
/*Count all rows returns 766*/
SELECT COUNT(*) FROM Producer
Комментарии:
1. В общем, полагаться на внешний вид
IS NULL
соOUTER JOIN
стороны-значит напрашиваться на неприятности. Нули-это мерзость. Используйте подзапрос с[NOT] IN
, согласно ответу @CurtLH; или с[NOT] EXISTS
.
Ответ №1:
Вместо использования соединения вы можете использовать подзапрос.
Например, этот запрос вернет всех производителей, у которых есть продукт.
SELECT *
FROM Producer
WHERE producerID IN (SELECT producerID FROM Products)
И этот запрос вернет всех производителей, у которых нет продукта.
SELECT *
FROM Producer
WHERE producerID NOT IN (SELECT producerID FROM Products)