2013-06-19 54 views
0

我有一个查询,按客户月份计算销售额。但是,我有一些客户在一个月内没有购买。对于这些情况,我希望MonthNum字段的SalesDlr值为0,但MonthNum值仍然需要实际的月份数。目前,我在下面的查询中没有获得MonthNum值:如何添加缺失的月份?

SELECT 
    a.Customer, 
    a.CustomerName, 
    a.MonthNum, 
    a.FiscalYear, 
    a.SalesDlr 
FROM 
(SELECT 
    sd.SBCUST AS Customer, 
    sd.RMNAME AS CustomerName, 
    fc.FiscalMonthNum AS MonthNum, 
    fc.FiscalYear, 
    SUM(sd.SBEPRC) AS SalesDlr 
FROM 
    dbo.SalesData sd 
    LEFT OUTER JOIN dbo.FiscalCalendar fc ON fc.FiscalDate = sd.SBINDT 
WHERE 
    sd.SBTYPE = 'O' 
AND 
    sd.SBINDT > '2012-12-31' 
AND 
    sd.SBCLS NOT IN ('1500') 
GROUP BY 
    sd.SBCUST, 
    sd.RMNAME, 
    fc.FiscalMonthNum, 
    fc.FiscalYear 
)a 
GROUP BY 
    a.Customer, 
    a.CustomerName, 
    a.MonthNum, 
    a.FiscalYear, 
    a.SalesDlr 
ORDER BY 
    a.Customer, 
    a.MonthNum, 
    a.FiscalYear 

我该如何解决这个问题?

+0

博客系列,你可能会发现有用:http://www.sqlperformance.com/generate-a -set-1 http://www.sqlperformance.com/generate-a-set-2 http://www.sqlperformance.com/generate-a-set-3 –

+0

“对于这些情况,我希望MonthNum字段有一个0的值为“....你确定?或者你是否希望0为SalesDlr – Talasila

+0

我希望0为SalesDlr,但我还需要MonthNum字段为没有销售的月份有一个值。例如,客户ABC在2013年4月开始购买,然后我需要2013年1月的SalesDlr值为0以及2月和3月。 – tsqln00b

回答

1

我猜你的SalesData每个月都没有每个客户的条目。如果客户柯蒂斯在5月份不进行采购,那么他可能在5月份的SalesData中没有任何条目。因此,当您左侧与SalesData离开时,Curtis将不会为May定一行。

切换左连接的顺序也不够充分,因为那样只会为缺少的客户生成一个日期。因此,你真的想在不同的客户和不同月份之间的交叉连接,然后获得这些的总和:

with FilteredSalesData as (
    SELECT 
     sd.SBCUST as Customer, 
     sd.RMName as CustomerName, 
     sd.SBEPRC, 
     fc.FiscalMonthNum as MonthNum, 
     fc.FiscalYear 
    FROM dbo.SalesData sd 
    join FiscalCalendar fc ON fc.FiscalDate = sd.SBINDT 
     WHERE 
      sd.SBTYPE = 'O' 
     AND 
      sd.SBCLS NOT IN ('1500') 
), DistinctCustomers as (
    select distinct 
     SBCUST as Customer, 
     RMName as CustomerName 
    from FilteredSalesData 
), DistinctMonths as (
    select distinct 
     FiscalMonthNum as MonthNum, 
     FiscalYear 
    From FiscalCalendar 
    WHERE FiscalDate > '2012-12-31' 
) 
select 
    Customer, 
    CustomerName, 
    MonthNum, 
    FiscalYear, 
    SUM(sd.SBEPRC) as SalesDlr 
From DistinctCustomers dc 
CROSS JOIN DistinctMonths dm 
left Join FilteredSalesData sd 
    on sd.customer = dc.Customer 
    and sd.CustomerName = dc.CustomerName 
    and sd.MonthNum = dm.MonthNum 
    and sd.FiscalYear = dm.FiscalYear 
group by Customer, CustomerName, MonthNum, FiscalYear 
order by Customer, MonthNum, FiscalYear 
+0

您在声明中表示每个月没有每个客户的条目是正确的。但是,您的答案仍然不会产生预期的结果。 – tsqln00b

+0

@ tsqln00b好点。我错过了过滤器的位置。您可以在加入之前先使用子查询过滤SalesData。当我回到电脑时,我会编辑我的解决方案。 –

+0

SQL小提琴处理所有数据有点多...... – tsqln00b