Поиск статистики продаж по странам с использованием MySQL

#mysql

#mysql

Вопрос:

это мой набор данных

введите описание изображения здесь

Здесь мне нужно будет найти данные о продажах мотоцикла по стране вместе с доходом за 2018 год. выручка рассчитывается как количество * цена. вот как должен выглядеть вывод.

введите описание изображения здесь

это запрос, который я написал в mysql.

 select con.name as country_name
      , mo.name as motor_cycle_model
      , sum(sa.quantity*mo.price) as revenue

from sales sa
    left join country con on (con.id=sa.country_id)
    left join motorcycle_model mo on (mo.id=sa.model_id)
 where year(sales_date) = '2018'
 group by 1,2
 order by 1
 

но проблема здесь в том, что я не смог получить страны, в которых в 2018 году не было продаж.

Комментарии:

1. Если ваш запрос начинается с country и присоединяется к нему слева sales , то в списке будут все страны.

2. Или right join country

Ответ №1:

Попробуйте:

 select con.name as country_name
      , mo.name as motor_cycle_model
      , sum(sa.quantity*mo.price) as revenue

from country con
    left join sales sa on (con.id=sa.country_id)
    left join motorcycle_model mo on (mo.id=sa.model_id)
 where year(sales_date) = '2018'
 group by 1,2
 order by 1
 

РЕДАКТИРОВАТЬ: потому что, как прокомментировал @Strawberry, выше inner join

Выше inner join приведено потому, что при выполнении a left join вы не должны выполнять фильтр по полям из таблицы, к которой вы остаетесь присоединенным.

В этом случае выполняется левое соединение sales , и после этого результат ограничен из — за where yea(sales_date)=2018 . это приводит к тому, что из результата исключаются все страны, у которых нет продаж.

Исправленный оператор dbfiddle:

Сначала мы выбираем stock (как я его назвал), а затем выполняем левое соединение sales для 2018 года.

 select 
    stock.country_name
    , stock.motor_cycle_model
    , sum(COALESCE(sa.quantity * stock.price,0)) as revenue
from    
   (select con.id as cid
      , con.name as country_name
      , mo.id as mid
      , mo.name as motor_cycle_model
      , mo.price as price
    from country con
    cross join motorcycle_model mo
   ) stock
left join sales sa on sa.model_id=stock.mid
                  and sa.country_id=stock.cid
                  and year(sa.sales_date) = 2018
group by 1,2
order by 1;
 

вывод:

имя_страны_ motor_cycle_model выручка
Алжир МОТО400 0
Алжир YZM1000 0
Доминика МОТО400 250000
Доминика YZM1000 140000
Сан-Томе и Принсипи МОТО400 0
Сан-Томе и Принсипи YZM1000 560000

Комментарии:

1. Это внутреннее соединение

2. @Strawberry: я отредактировал ответ и попытался объяснить, почему исходный комментарий от / me был неправильным…

3. Обратите внимание, что фильтр диапазона предпочтительнее функции

4. Кроме того, я подозреваю, что ваш запрос можно было бы написать проще, но эй, если это сработает…

5. Я предполагаю, что это было бы более оптимально … dbfiddle.uk /…