Counting by Item & Channel by First Two Months Sold

只谈情不闲聊 提交于 2019-12-11 05:04:05

问题


Following up on my last question, Counting Items based on First Month Sold, I need to count items by the first two months they were sold but also need to group by channel along with item, along with total item qty sold as well.

See sample code below

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)

The output would look like the following

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

A count would only appear if it was sold during the first two months within the first time the item was ordered, where it could be one of several channels (I'm using Channel1, and 2 as examples but there could be several) but will always have one channel.I'd want to display all channels and show a count of 0 if there isn't anything there with the quantity also being 0 in that case (example, an item sold in one channel during those first two months but not the second channel).

Thanks!


回答1:


This does need a cross join now!

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

Results

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

It is now a simple thing to change the number of months covered in the first period. Just change the number of months in the dateadd function.




回答2:


This seems a bit tricky. One method is to generate all the rows you want with a cross join and then use a left join to bring in the count:

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;



回答3:


You will need all distinct channels and then do a left join like below..

;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


来源:https://stackoverflow.com/questions/39068325/counting-by-item-channel-by-first-two-months-sold

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!