проблема полного внешнего соединения - месяцы без дохода - PullRequest
0 голосов
/ 05 декабря 2018

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

with cte1 as (
select *
from (Values
    (1, 'jan'),
    (2, 'feb'),
    (3, 'mar'),
    (4, 'apr'),
    (5, 'may'),
    (6, 'jun'),
    (7, 'jul'),
    (8, 'aug'),
    (9, 'sep'),
    (10, 'oct'),
    (11, 'nov'),
    (12, 'dec')
) as T(monthnr, maand))
--This part calculates the monthly revenue (maand = month)
select x.regioncode, x.city, x.maand, x.monthlyrevenue, y.totalrevenue
from (
select v.regioncode, city, maand, COALESCE(SUM(oa.amount * pp.price), 0) as monthlyrevenue
from salesregion s
join employee e
on s.regionmgr = e.employeeID
join customer c
on left(c.postalcodehousenumber, 4) between s.pcbegin and s.pcend
join orders o
on o.customerID = c.customerID
join orderamount oa
on oa.orderid = o.orderid
join productprice pp
on pp.productid = oa.productid
join cte1
on month(orderdate) = monthnr
where (o.orderdate > pp.begindate and o.orderdate < pp.enddate) and year(orderdate) = 2014
group by regioncode, city, maand) x
CROSS JOIN
(--This code calculates the total revenue per city.
select city, SUM(oa.amount * pp.price) as totalrevenue
from salesregion s
join employee e
on s.regionmgr = e.employeeID
join customer c
on left(c.postalcodehousenumber, 4) between s.pcbegin and s.pcend
join orders o
on o.customerID = c.customerID
join orderamount oa
on oa.orderid = o.orderid
join productprice pp
on pp.productid = oa.productid
where (o.orderdate > pp.begindate and o.orderdate < pp.enddate) and year(orderdate) = 2014
group by city
)y
where x.city = y.city

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

То, что я сейчас получаю, можно увидеть на изображении ниже.Слева направо на изображении: Код региона, город, месяц, доход, общая сумма дохода .

В результате я пытаюсь отобразить все месяцы для каждого города,даже если у них не было никакого дохода в этом месяце.В настоящее время отображаются только месяцы с доходом в этом месяце (я хочу, чтобы он отображал город: Erp, месяц: январь, доход: либо «0», либо «ноль». текущий результат

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Я создал 4 CTE

  • GetMonths - ваш CTE1
  • Доход - доход по городам, регионам, поэтому позднее перекрестное объединение должно выполнять меньше работы.
  • GetUniqueCityRegion - если вы хотите все месяцы по городу / региону, тогда мне нужно было
  • GetUniqueCityRegionMonth - тогда будут получены все месяцы для каждого региона города.

.Для меня проблема заключалась в том, что когда вы говорите «видеть все месяцы», то, что, таким образом, требует список городов по месяцам

Полностью не проверено, поскольку не было предоставлено никаких таблиц / выборочных данных, и на их составление уходит слишком много времени.

WITH GetMonths as (SELECT *
              FROM (Values
                   (1, 'jan'),(2, 'feb'),(3, 'mar'),(4, 'apr'),(5, 'may'),(6, 'jun'),
                   (7, 'jul'),(8, 'aug'),(9, 'sep'),(10, 'oct'),(11, 'nov'),(12, 'dec')) as T(monthnr, maand)),
Revenue as (SELECT regioncode, city, sum(coalesce(oaamount*pp.price,0)) as RecordRevenue, month(o.Orderdate) as Mo 
            FROM salesregion s
            JOIN employee e
              on s.regionmgr = e.employeeID
            JOIN customer c
              on left(c.postalcodehousenumber, 4) between s.pcbegin and s.pcend
            JOIN orders o
              on o.customerID = c.customerID
            JOIN orderamount oa
              on oa.orderid = o.orderid
            JOIN productprice pp
              on pp.productid = oa.productid
            WHERE o.orderdate > pp.begindate 
              and o.orderdate < pp.enddate) 
              and year(o.orderdate) = 2014
            GROUP BY RegionCode, City),
GetUniqueRegionCity as (SELECT DISTINCT REGIONCODE, City 
         FROM Revenue)
GetUniqueRegionCityMonth as (SELECT RegionCode, City, monthnr, maand
         FROM GetUniqueRegionCity
         CROSS JOIN GetMonths)

--Now get the Total Revenue by City/Region  We left join to revenue from GetUniqueRegionCityMonth to ensure each city/region has all months
    SELECT x.regioncode
         , x.city
         , x.maand
         , x.monthlyrevenue
         , coalesce(sum(RecordRevenue) over (partition by x.city, R.Mo),0) as RevenueCity
         , coalesce(sum(RecordRevenue) over (partition by x.RegionCode, R.Mo),0) RevenueRegion
    FROM GetUniqueRegionCityMonth x
    LEFT JOIN Revenue R
      on R.RegionCode = x.RegionCode
     and R.City = x.City
     and R.Mo = x.MonthNr
0 голосов
/ 05 декабря 2018

Вам не нужно добавлять перекрестные заявки, чтобы найти TotalRevenue.Просто вы можете использовать SUM(City) OVER(PARTITION BY City) Я изменил и попытался упростить ваш запрос.Я верю, что это может помочь вам.

WITH cte1
AS
(SELECT
        *
    FROM (VALUES(1, 'jan'),
    (2, 'feb'),
    (3, 'mar'),
    (4, 'apr'),
    (5, 'may'),
    (6, 'jun'),
    (7, 'jul'),
    (8, 'aug'),
    (9, 'sep'),
    (10, 'oct'),
    (11, 'nov'),
    (12, 'dec')
    ) AS T (monthnr, maand))
--This part calculates the monthly revenue (maand = month)
SELECT
    x.regioncode
   ,x.city
   ,cte1.maand
   ,x.monthlyrevenue
   ,x.totalrevenue
FROM cte1
LEFT JOIN 
    (SELECT
            s.regioncode
           ,city
           ,MONTH(orderdate) OrderMonth
           ,COALESCE(SUM(oa.amount * pp.price), 0) AS monthlyrevenue
           ,SUM(COALESCE(SUM(oa.amount * pp.price), 0)) OVER (PARTITION BY city) totalrevenue
        FROM salesregion s
        JOIN employee e ON s.regionmgr = e.employeeID
        JOIN customer c ON LEFT(c.postalcodehousenumber, 4) BETWEEN s.pcbegin AND s.pcend
        JOIN orders o ON o.customerID = c.customerID
        JOIN orderamount oa ON oa.orderid = o.orderid
        JOIN productprice pp ON pp.productid = oa.productid
        WHERE (o.orderdate > pp.begindate
        AND o.orderdate < pp.enddate)
        AND YEAR(orderdate) = 2014
        GROUP BY s.regioncode
                ,city
                ,MONTH(orderdate)) x ON CTE1.monthnr = OrderMonth
0 голосов
/ 05 декабря 2018

Это не проверено, но я переместил несколько вещей, чтобы упростить ваш запрос.Похоже, что перекрестное соединение дает мне общий доход для каждого города за весь период времени, а не ежемесячный доход, поэтому я добавил функцию суммирования, которая полностью исключает необходимость запроса «у».Возможно, я неправильно истолковал ваше намерение, поэтому, если оно не дает правильного результата, попробуйте изменить поле в выражении «partition».Это будет работать только с SQL Server 2012 и более поздними версиями:

with cte1 as (
select *
from (Values
(1, 'jan'),
(2, 'feb'),
(3, 'mar'),
(4, 'apr'),
(5, 'may'),
(6, 'jun'),
(7, 'jul'),
(8, 'aug'),
(9, 'sep'),
(10, 'oct'),
(11, 'nov'),
(12, 'dec')
) as T(monthnr, maand))
--This part calculates the monthly revenue (maand = month)
select x.regioncode
,x.city
,x.maand
,x.revenue
,sum(x.revenue) over (partition by x.maand) as MonthlyRevenue
from (
select s.regioncode, s.city, cte1.maand, COALESCE(SUM(cr.revenue), 0) as Revenue
from salesregion s
join employee e
on s.regionmgr = e.employeeID
join customer c
on left(c.postalcodehousenumber, 4) between s.pcbegin and s.pcend
cross join cte1
left join
(
select o.customerid
,m.monthnr
,sum(oa.amount * pp.price) as Revenue
from orders o
join orderamount oa
on oa.orderid = o.orderid
join productprice pp
on pp.productid = oa.productid
join cte1 m
on month(o.orderdate) = m.monthnr
where (o.orderdate > pp.begindate and o.orderdate < pp.enddate) and year(orderdate) = 2014
group by o.customerid, m.monthnr
) cr
on c.customerid = cr.customerid
and cte1.monthnr = cr.monthnr
group by s.regioncode, s.city, cte1.maand
) x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...