MySQL: возвращение отсчетов (*) с NULL или 0 значениями - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть три таблицы CustomerSales & Icecream. В целях понимания есть одно мороженое в каждой продаже.

CustomerSales Таблица содержит (CustomerId, PurchaseId, почтовый индекс, IcecreamID)

Ice_Cream содержит (Ice_Cream Name, Ice_Cream Id)

Я пытаюсь написать запрос, который возвращает количество продаж шоколадного мороженого на каждый почтовый индекс (почтовый индекс), но я также хочу знать, какие почтовые индексы имели нулевые продажи. В настоящее время он возвращает только те почтовые индексы, у которых были продажи.

SELECT C.postcode, COUNT(*) AS TOTAL SALES
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;

Это близко к тому, что я хочу, но включает только почтовые индексы, которые сделали продажи. Я также хочу включить почтовые индексы, которые сделали 0 продаж шоколадного мороженого в 2019 году.

Как бы я это сделал? Я пробовал с накопительным пакетом, но думаю, что я делаю это неправильно.

Я также думал,

SELECT C.postcode, COUNT(*) AS TOTAL SALES
FROM CustomerSales C OUTER LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;

Я думаю, что проблема в том, что count возвращает значения строк.

Ответы [ 5 ]

2 голосов
/ 07 ноября 2019

Подсчитайте идентификатор закупки вместо *, я думаю, что это должно вернуть ожидаемые результаты:

SELECT C.postcode, COUNT(C.PurchaseId) AS TOTAL SALES
FROM CustomerSales C OUTER LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
1 голос
/ 07 ноября 2019

Проблема, которую я вижу, заключается в том, что вы выполняете объединение, а затем подсчитываете количество возвращенных записей, поэтому по умолчанию записи, для которых нет продаж, не заканчиваются в объединении.

Тип объединения важен здесь, я думаю, ЛЕВОЕ СОЕДИНЕНИЕпокажет все данные из первой таблицы, даже если в объединенной таблице данные не найдены, а затем вы посчитаете поля из объединенной таблицы, которые будут возвращать NULL, если ничего не найдено

Примерно так:

SELECT C.postcode, COUNT(I.name) AS TOTAL SALES
FROM CustomerSales C LEFT JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode;
1 голос
/ 07 ноября 2019
SELECT C.postcode, COUNT(*) AS TOTAL_SALES
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
GROUP BY C.postcode

union

select c.postcode, '0' as TOTAL_SALES
FROM CUSTOMERSALES C 
where c.postcode not in(select cs.postcode from 
FROM CustomerSales C JOIN IceCream I
ON C.icecreamID = I.id AND
WHERE I.name = "Chocolate" AND C.saleyear = "2019"
);
0 голосов
/ 07 ноября 2019

Для ясности, вы хотите использовать LEFT JOIN, переместить условие на I в предложение ON и изменить COUNT():

SELECT C.postcode, COUNT(i.id) AS TOTAL SALES
FROM CustomerSales C LEFT JOIN
     IceCream I
     ON C.icecreamID = I.id AND
        I.name = 'Chocolate'
WHERE C.saleyear = 2019
GROUP BY C.postcode;
0 голосов
/ 07 ноября 2019

Если вы хотите ALL почтовые индексы, то вы должны LEFT соединить DISTINCT почтовые индексы с CustomerSales, а затем с IceCream:

SELECT p.postcode, COUNT(C.PurchaseId) AS TOTAL_SALES
FROM (
  SELECT DISTINCT postcode
  FROM CustomerSales
) p LEFT JOIN CustomerSales C 
ON C.postcode = p.postcode AND C.saleyear = '2019'
LEFT JOIN IceCream I ON C.icecreamID = I.id AND I.name = 'Chocolate'
GROUP BY p.postcode;
...