ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ с ВНУТРЕННИМ СОЕДИНЕНИЕМ для равенства общего числа строк

#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)