Отображение значения по месяцам, когда данных не существует

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

Я использую SQL Server, и я написал приведенный ниже SQL-запрос, чтобы показать мне имя клиента, название города, продукт, количество продаж, год продажи, месяц продажи и имя дистрибьютора, а также количество, которое я продал в определенном месяце, однако я хочу, чтобы запрос отображался по месяцам, даже если нет данных за месяц.

 SELECT dbo.Customerdetl.cust_name, dbo.Towndetl.town_name, dbo.productdetl.prod_desc, dbo.SalesSummary.sales_qty, dbo.SalesSummary.year_numb, dbo.SalesSummary.month_numb,dbo.DistributorDetl.DISTNAME FROM dbo.SalesSummary INNER JOIN  dbo.productdetl ON dbo.SalesSummary.ProductCode = dbo.productdetl.ProductCode INNER JOIN  dbo.DistributorDetl ON dbo.SalesSummary.DistCode = dbo.DistributorDetl.DistCode INNER JOIN  dbo.Customerdetl ON dbo.SalesSummary.cust_code = dbo.Customerdetl.cust_code INNER JOIN  dbo.Towndetl ON dbo.SalesSummary.town_code = dbo.Towndetl.town_code  WHERE (dbo.SalesSummary.year_numb = 2021) AND (dbo.Customerdetl.cust_name = N'Janani Pharmacy') AND (dbo.productdetl.prod_desc = N'Mycotin')  

Результат, который я получаю, таков:

Имя пользователя Город Продукт Количество продаж Год Месяц Имя распространителя
Аптека Джанани ХАНВЕЛЛА Микотин 10 2021 7 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 10 2021 4 НЕГА

то, что я хотел бы получить, это:

Имя пользователя Город Продукт Количество продаж Год Месяц Имя распространителя
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 1 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 2 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 3 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 10 2021 4 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 5 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 6 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 10 2021 7 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 8 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 9 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 10 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 11 НЕГА
Аптека Джанани ХАНВЕЛЛА Микотин 0 2021 12 НЕГА

Я также попытался использовать левое соединение, но это не сработало.

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

1. Очень распространенная проблема… таблица календаря Google.

Ответ №1:

Я предполагаю, что таблица продаж не хранит записей без продаж. Что-то вроде этого должно в «теории» создать таблицу, в которой есть все, что вам нужно.

  1. TABLENEEDS получает все разные данные о годе, коде дистрибутива, коде продукта, коде города и коде пользователя
  2. ПОСТРОЕНИЕ выполняет перекрестное соединение, которое применяет все месяцы ко всем различным наборам в TABLENEEDS (при условии, что dbo.SalesSummary.month_numb имеет все 12 месяцев)
  3. ADDSALESBACK делает именно это-левое соединение по всем критериям, которое превращает нулевые значения там, где продаж не существует, в нули.

Окончательный выбор просто отображает ADDSALESBACK — вы бы просто выполнили другие соединения из таблицы ADDSALESBACK вместо dbo.Распродажа

 WITH TABLENEEDS AS ( SELECT DISTINCT  dbo.SalesSummary.year_numb,  dbo.SalesSummary.DistCode,  dbo.SalesSummary.ProductCode,  dbo.SalesSummary.town_code,  dbo.SalesSummary.cust_code, FROM dbo.SalesSummary )  ,  BUILDOUT AS( SELECT * FROM TABLENEEDS CROSS JOIN (SELECT DISTINCT dbo.SalesSummary.month_numb FROM dbo.SalesSummary) AS MONTHSFORBUILDOUT )  ,  ADDSALESBACK AS( SELECT BUILDOUT.*, COALESCE(dbo.SalesSummary.sales_qty, 0) AS sales_qty FROM BUILDOUT LEFT JOIN dbo.SalesSummary ON dbo.SalesSummary.year_numb = BUILDOUT.year_numb AND dbo.SalesSummary.DistCode = BUILDOUT.DistCode AND dbo.SalesSummary.ProductCode, = BUILDOUT.ProductCode AND dbo.SalesSummary.town_code = BUILDOUT.town_code AND dbo.SalesSummary.cust_code = BUILDOUT.cust_code AND  dbo.SalesSummer.month_numb = BUILDOUT.month_numb)  SELECT * FROM ADDSALESBACK  

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

1. Привет, спасибо за ответ, однако у меня, похоже, возникла проблема, я получаю неправильный синтаксис рядом с»)». ожидая, что as, for_path, идентификатор или quoted_id в части ПОСТРОЕНИЯ в вашем коде в конце, последняя скобка в части ПОСТРОЕНИЯ кода. если это может помочь прояснить, в чем причина, которая была бы наиболее признательна

2. Я предполагаю, что, поскольку это ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ использует подзапрос, для него требовалось имя — я добавил КАК MONTHSFORBUILDOUT в качестве имени в своем посте

3. Привет, это сработало, я получаю дубликаты: как показано по ссылке snipboard.io/5rKsN9.jpg количество продаж должно быть только для 4-го и 7-го месяцев, остальные должны быть равны нулю или нулю для количества продаж

4. Мне не хватало определителя в предложении where для month_numb — add И dbo. SalesSummer.month_numb = СБОРКА.month_numb — я также отредактировал свой код