2017-03-07 80 views
2

没有数据可以说我有一个销售报告:获取数据PR月份一行即使有那个月

Salesman | Sales | Month | yr | 
    A  5  1  2016 
    A  12  1  2017 
    A  3  1  2017 
    A  25  5  2017 
    B  20  4  2017 
    B  49  6  2017 

如果我想看看总销售额PR推销员,我会做这样的事情:

SELECT salesman, sum(SALES), MONTH from SALESTABLE GROUP BY Salesman, Mnth where year = 2017 

并获得:

Salesman | Sales | Mnth | yr | 
    A  15  1 2017 
    A  25  5 2017 
    B  20  4 2017 
    B  49  6 2017 

但是我想以下几点:

Salesman | Sales | Mnth | yr | 
    A   15  1  2017 
    A   0  2  2017 
    A   0  3  2017 
    ... 
    A   25  5  2017 
    ... 

我已经试过如下:

DECLARE @MonthTable TABLE 
(
Monthnumber int 
) 


DECLARE @cnt int = 0 
while @cnt < 12 
BEGIN 
    SET @cnt = @cnt+1 
    Insert into @MonthTable (monthnumber) values (@cnt) 
END 


SELECT salesman, 
    sum(SALES), 
    monthnumber 
FROM SALESTABLE 
RIGHT JOIN @MonthTable ON monthnumber = mnth  
GROUP BY Salesman, monthnumber 

然而这给出了 “推销员” 一NULL,符合市场预期。

+1

一种方法是创建一个[日历表](http://www.sqlservercentral.com/blogs/dwainsql/2014/03/30/calendar-tables-在-T-SQL /)。该表格将为您提供一些内容。 –

回答

3

通过生成月份列表和交叉连接推销员和一年中的不同列表加入回表,我们可以通过像这样产生的月龄组和金额:

;with months as (
    select Mnth 
    from (values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) t(Mnth) 
) 
select 
    s.Salesman 
    , s.Yr 
    , m.Mnth 
    , Sales = coalesce(sum(t.Sales),0) 
from (
    select distinct Salesman, yr 
    from t 
) as s 
    cross join months m 
    left join t 
    on s.Salesman = t.Salesman 
    and s.Yr = t.Yr 
    and m.Mnth = t.[Month] 
where s.yr = 2017 
group by s.Salesman, s.Yr, m.Mnth 

rextester演示:http://rextester.com/ZOHB53144

回报:

+----------+------+------+-------+ 
| Salesman | Yr | Mnth | Sales | 
+----------+------+------+-------+ 
| A  | 2017 | 1 | 15 | 
| A  | 2017 | 2 |  0 | 
| A  | 2017 | 3 |  0 | 
| A  | 2017 | 4 |  0 | 
| A  | 2017 | 5 | 25 | 
| A  | 2017 | 6 |  0 | 
| A  | 2017 | 7 |  0 | 
| A  | 2017 | 8 |  0 | 
| A  | 2017 | 9 |  0 | 
| A  | 2017 | 10 |  0 | 
| A  | 2017 | 11 |  0 | 
| A  | 2017 | 12 |  0 | 
| B  | 2017 | 1 |  0 | 
| B  | 2017 | 2 |  0 | 
| B  | 2017 | 3 |  0 | 
| B  | 2017 | 4 | 20 | 
| B  | 2017 | 5 |  0 | 
| B  | 2017 | 6 | 49 | 
| B  | 2017 | 7 |  0 | 
| B  | 2017 | 8 |  0 | 
| B  | 2017 | 9 |  0 | 
| B  | 2017 | 10 |  0 | 
| B  | 2017 | 11 |  0 | 
| B  | 2017 | 12 |  0 | 
+----------+------+------+-------+ 
+0

谢谢你的出色建议。我很抱歉,但现在回想起来,我应该也包括一年。我很抱歉,我以前没有这样做过。 –

+0

@ B.Doe12我已经更新了我的答案,包括'Yr' – SqlZim

0

正如你已经正确地创建了一个月的表为没有销售这几个月每月提供的条目,你需要一个主销售人员表为销售员提供那些没有销售的月份的信息。

以最简单的形式,您可以通过获得distinct salesmansalesdata表中生成主销售员表;理想情况下,您可能希望使用单独的销售员表,每个销售员有一个条目。

然后查询变为:

SELECT salesman, 
    sum(SALES), 
    monthnumber 
FROM SALESTABLE 
RIGHT JOIN @MonthTable ON monthnumber = mnth  
GROUP BY Salesman, monthnumber 

SELECT 
    salesmanlist.salesman 
    , SUM(salestable.sales) 
    , monthtable.monthnumber 
FROM 
    (SELECT DISTINCT salesman FROM salestable) as salesmanlist -- <-- Key change 
    CROSS JOIN @MonthTable as monthtable 
    LEFT JOIN salestable 
    ON  salesmanlist.salesman = salestable.salesman 
     AND salestable.mnth = monthtable.monthnumber 
+0

Ack,被SqlZim殴打了几分钟! – Phylyp