跟进我的上一个问题,Counting Items based on First Month Sold,我需要在销售的前两个月内计算物品,但也需要按渠道分组以及物品,以及销售的总物品数量。
参见下面的示例代码
DECLARE @sales table(
itemnumber int,
saledate date,
channeltype varchar,
ordid varchar,
orditemqty int)
INSERT INTO @sales VALUES(43029, '2011-26-03', Channel2, 1, 5)
INSERT INTO @sales VALUES(43029, '2011-26-03', Channel2, 2, 6)
INSERT INTO @sales VALUES(43029, '2011-26-03', Channel2, 3, 2)
INSERT INTO @sales VALUES(43029, '2011-26-03', Channel2, 4, 3)
INSERT INTO @sales VALUES(43029, '2011-26-03', Channel2, 4, 1)
INSERT INTO @sales VALUES(43029, '2011-26-04', Channel2, 5, 5)
INSERT INTO @sales VALUES(43029, '2011-26-04', Channel2, 5, 7)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel1, 5, 8)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel2, 6, 1)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel1, 7, 2)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel2, 8, 4)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel2, 8, 6)
INSERT INTO @sales VALUES(43030, '2011-26-04', Channel2, 8, 1)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 8)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 9)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 10)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 11)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 1)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 9, 4)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel2, 19, 7)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel2, 19, 9)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 25, 10)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 25, 11)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel1, 25, 10)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel2, 27, 1)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel2, 27, 4)
INSERT INTO @sales VALUES(43030, '2011-26-05', Channel2, 27, 6)
INSERT INTO @sales VALUES(43050, '2011-26-05', Channel1, 28, 8)
INSERT INTO @sales VALUES(43050, '2011-26-05', Channel2, 29, 9)
INSERT INTO @sales VALUES(43050, '2011-26-05', Channel1, 39, 1)
INSERT INTO @sales VALUES(43050, '2011-26-05', Channel2, 30, 4)
INSERT INTO @sales VALUES(43050, '2011-26-06', Channel1, 31, 9)
INSERT INTO @sales VALUES(43050, '2011-26-06', Channel1, 31, 1)
INSERT INTO @sales VALUES(43050, '2011-26-07', Channel1, 45, 6)
INSERT INTO @sales VALUES(43090, '2011-26-07', Channel2, 61, 3)
INSERT INTO @sales VALUES(43090, '2011-26-07', Channel2, 61, 4)
INSERT INTO @sales VALUES(43090, '2011-26-07', Channel2, 61, 5)
INSERT INTO @sales VALUES(43090, '2011-26-07', Channel2, 61, 8)
INSERT INTO @sales VALUES(43090, '2011-26-08', Channel1, 71, 2)
INSERT INTO @sales VALUES(43090, '2011-26-08', Channel1, 71, 3)
INSERT INTO @sales VALUES(43090, '2011-26-09', Channel1, 76, 5)
输出如下所示
ITEMNO| CHANNELTYPE | YEARMONTH | COUNT | QTY
---------------------------------------------
43029 | Channel1 | 03-2011 | 0 | 0
43029 | Channel2 | 03-2011 | 7 | 29
43030 | Channel1 | 04-2011 | 11 | 84
43030 | Channel2 | 04-2011 | 9 | 39
43050 | Channel1 | 05-2011 | 4 | 19
43050 | Channel2 | 05-2011 | 2 | 13
43090 | Channel1 | 07-2011 | 2 | 5
43090 | Channel2 | 07-2011 | 4 | 20
只有在第一次订购商品的前两个月内出售时才会出现计数,其中可能是多个渠道之一(我使用的是Channel1,而2则是示例,但可能有几个)但是总是有一个频道。我想要显示所有频道并显示0的数量,如果没有任何东西,那么在这种情况下数量也是0(例如,在第一个频道中在一个频道中销售的项目)两个月但不是第二个频道)。
谢谢!
答案 0 :(得分:2)
这看起来有点棘手。一种方法是使用cross join
生成所需的所有行,然后使用left join
引入计数:
with icym as (
select s.item_id, s.channel,
format(saledate, 'yyyy-mm') as yyyymm,
count(*) as cnt
from @sales s
group by s.item_id, s.channel,
format(saledate, 'yyyy-mm') as yyyymm,
)
select iy.item_id, iy.yyyymm, c.channel, coalesce(icym.cnt, 0)
from (select distinct s.item_id, yyyymm from icym) iy cross join
(select distinct channel from icym) c left join
icym
on icym.item_id = iy.item_id and icym.yyyymm = iy.yyyymm and
icym.channel = c.channel;
答案 1 :(得分:1)
现在需要交叉加入!
DECLARE @sales table(
itemnumber int,
saledate date,
channeltype varchar(10),
ordid varchar,
orditemqty int)
INSERT INTO @sales VALUES(43029, '2011-03-26', 'Channel2', 1, 5)
INSERT INTO @sales VALUES(43029, '2011-03-26', 'Channel2', 2, 6)
INSERT INTO @sales VALUES(43029, '2011-03-26', 'Channel2', 3, 2)
INSERT INTO @sales VALUES(43029, '2011-03-26', 'Channel2', 4, 3)
INSERT INTO @sales VALUES(43029, '2011-03-26', 'Channel2', 5, 1)
INSERT INTO @sales VALUES(43029, '2011-04-26', 'Channel2', 6, 5)
INSERT INTO @sales VALUES(43029, '2011-04-26', 'Channel2', 7, 7)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel1', 8, 8)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel2', 9, 1)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel1', 10, 2)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel2', 11, 4)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel2', 12, 6)
INSERT INTO @sales VALUES(43030, '2011-04-26', 'Channel2', 13, 1)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 14, 8)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 15, 9)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 16, 10)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 17, 11)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 18, 1)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 19, 4)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel2', 20, 7)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel2', 21, 9)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 22, 10)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 23, 11)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel1', 24, 10)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel2', 25, 1)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel2', 26, 4)
INSERT INTO @sales VALUES(43030, '2011-05-26', 'Channel2', 27, 6)
INSERT INTO @sales VALUES(43050, '2011-05-26', 'Channel1', 28, 8)
INSERT INTO @sales VALUES(43050, '2011-05-26', 'Channel2', 29, 9)
INSERT INTO @sales VALUES(43050, '2011-05-26', 'Channel1', 30, 1)
INSERT INTO @sales VALUES(43050, '2011-05-26', 'Channel2', 31, 4)
INSERT INTO @sales VALUES(43050, '2011-06-26', 'Channel1', 32, 9)
INSERT INTO @sales VALUES(43050, '2011-06-26', 'Channel1', 33, 1)
INSERT INTO @sales VALUES(43050, '2011-07-26', 'Channel1', 34, 6)
INSERT INTO @sales VALUES(43090, '2011-07-26', 'Channel2', 35, 3)
INSERT INTO @sales VALUES(43090, '2011-07-26', 'Channel2', 36, 4)
INSERT INTO @sales VALUES(43090, '2011-07-26', 'Channel2', 37, 5)
INSERT INTO @sales VALUES(43090, '2011-07-26', 'Channel2', 38, 8)
INSERT INTO @sales VALUES(43090, '2011-08-26', 'Channel1', 39, 2)
INSERT INTO @sales VALUES(43090, '2011-08-26', 'Channel1', 40, 3)
INSERT INTO @sales VALUES(43090, '2011-09-26', 'Channel1', 41, 5)
SELECT t.itemnumber, t.channeltype,
right(convert(varchar, firstsaledate, 106), 8) AS firstsale,
SUM(t.cnt) AS salecount, sum(t.qty) AS saleqty
FROM
(
SELECT fsdc.itemnumber, fsdc.firstsaledate, fsdc.channeltype,
CASE WHEN s.ordid IS NULL THEN 0 ELSE 1 END AS cnt,
COALESCE(s.orditemqty, 0) qty
FROM
(
SELECT fsd.itemnumber, fsd.firstsaledate, fsd.targetdate,
c.channeltype
FROM
(
SELECT mns.itemnumber, mns.firstsaledate, DATEADD(m, 2,
DATEFROMPARTS(YEAR(mns.firstsaledate), MONTH(mns.firstsaledate), 1))
as targetdate
FROM
(
SELECT itemnumber, Min(saledate) as firstsaledate FROM @sales
GROUP BY itemnumber
) mns
) fsd
CROSS JOIN
(
SELECT DISTINCT channeltype FROM @sales
) c
) fsdc
LEFT JOIN @sales s
ON s.itemnumber = fsdc.itemnumber and s.channeltype = fsdc.channeltype
AND s.saledate < fsdc.targetdate
) t
GROUP BY t.itemnumber, t.channeltype, t.firstsaledate
结果
itemnumber channeltype firstsale salecount saleqty
43029 Channel1 Mar 2011 0 0
43029 Channel2 Mar 2011 7 29
43030 Channel1 Apr 2011 11 84
43030 Channel2 Apr 2011 9 39
43050 Channel1 May 2011 4 19
43050 Channel2 May 2011 2 13
43090 Channel1 Jul 2011 2 5
43090 Channel2 Jul 2011 4 20
现在改变第一个时期所涵盖的月数是一件简单的事情。只需更改dateadd函数中的月数。
答案 2 :(得分:0)
您将需要所有不同的频道,然后像下面那样进行左连接..
;With cte
as
(select
itemnumber,saledate,channeltype,
dense_rank() over (partition by itemnumber order by cast(month(convert(datetime,saledate,103)) as varchar(2))+'/'+cast(year(convert(datetime,saledate,103)) as varchar(4))) as rownum
from
#temp
),
channel
as
(
select distinct channeltype from #temp)
select
c.channeltype,
itemnumber,
cast(month(convert(datetime,saledate,103)) as varchar(2))+'/'+cast(year(convert(datetime,saledate,103)) as varchar(4)) as datetimesale,
isnull(sum(rownum),0) as salescount
from channel c
left join
cte c1
on c.channeltype=c1.channeltype
where rownum=1
group by
itemnumber,
cast(month(convert(datetime,saledate,103)) as varchar(2))+'/'+cast(year(convert(datetime,saledate,103)) as varchar(4)),
c.channeltype