Transform query on two columns in SQL 2008

The table I am working with looks like

Date         | Category | Product | Qty | Amt

06/01/15 | A               | X             | 2     | 5
06/07/15 | A               | Y             | 1     | 4
06/14/15 | A               | Y             | 2     | 6

I want both Qty and Amt as the Pivot columns grouped by week number, Category and product. Below example is only for week 23 and 24. I need a table that could start from week1 and go upto week52

Category | Product | Week23Qty | Week23Amt | Week24Qty | Week24Amt
A               | X            | 5                    | 4                    | 3                    | 5
A               | Y            | 1                    | 4                    | 2                    | 6

I have written the following query

Select Category, product,
CASE (datepart(wk,[DATE])) WHEN '23' THEN AVG(Amt) END AS WEEK23Amt,
CASE (datepart(wk,[DATE])) WHEN '23' THEN SUM(Qty) END AS WEEK23Qty,
CASE (datepart(wk,[DATE])) WHEN '24' THEN AVG(Amt) END AS WEEK24Amt,
CASE (datepart(wk,[DATE])) WHEN '24' THEN SUM(Qty) END AS WEEK24Qty
From mySalesTable
WHERE Category = 'A'
 GROUP BY   datepart(wk,[DATE]),Category,Product
 ORDER BY Product


But because of the grouping I am instead getting

Category | Product | Week23Qty  | Week23Amt | Week24Qty | Week24Amt
A               | X            | 5                     | 4                     | NULL           | NULL
A               | X            | NULL              | NULL             | 3                   | 5
A               | Y            | 1                     | 4                     | NULL            | NULL
A               | Y            | NULL              | NULL             | 2                    | 6

Also, the query I have written will get clumsy when I include all week (1-52). I am not sure how to use a transform query if I need 2 pivot columns Week#Qty and Week#Amt.

Can you please help?
Angel02Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sameer2010Commented:
select *
from 
(
  select category+'||'+product, datepart(wk,[DATE])) week, amt
  from mySalesTable
) src
pivot
(
  avg(amt)
  for week in ([1], [2], [3],[4],....[52])
) piv

Open in new window

Do a similar one for Quantity and then do an inner join for overall result
0
Angel02Author Commented:
Thank you! This is how I have written the query for certain weeks. I needed each weeks Amt and Qty side by side, so I mentioned the column names explicitly. Is there a better way to do this?
Also I needed the sum of all the "Qty" for a given product in all weeks. So I manually added the column values like below. Please let me know what you think.

Select tblAmt.Category, tblAmt.product, (ISNULL(tblQty.[1],0)+ ISNULL(tblQty.[2],0)+ ISNULL(tblQty.[3],0)+ ISNULL(tblQty.[4],0)+ ISNULL(tblQty.[23],0)+ ISNULL(tblQty.[24],0)) as TotalSold,
 tblAmt.[1],tblQty.[1], tblAmt.[2],tblQty.[2], tblAmt.[3], tblQty.[3],
 tblAmt.[4],tblQty.[4],tblAmt.[22],tblQty.[22],tblAmt.[23],tblQty.[23],tblAmt.[24],tblQty.[24],tblAmt.[25],tblQty.[25] from (select *
from
(
  select Category, product, datepart(wk,[DATE]) [week], Amt  from myTable
   where (TYPE ='N' OR Type = 'W' OR Type='O') AND ([DATE] BETWEEN '6/1/2014' AND '6/14/2014')
  ) src1
pivot
(
  avg(Amt)
  for week in ([1], [2], [3],[4],[22],[23],[24],[25])
) piv) tblAmt
INNER JOIN
(select *
from
(
  select Category, product, datepart(wk,[DATE]) [week], Qty  from myTable
  where (TYPE ='N' OR Type = 'W' OR Type='O') AND ([DATE] BETWEEN '6/1/2014' AND '6/14/2014')
  ) src2
pivot
(
  SUM(Qty)
  for week in ([1], [2], [3],[4],[22],[23],[24],[25])
) piv) tblQty
ON tblAmt.product = tblQty.product
where tblAmt.Category  =’ A’
order by tblAmt.Category, tblAmt.product
0
sameer2010Commented:
The only way you could do this is using dynamic SQL. Let me know if that's ok. The above query would remain the same, just the columns would be renamed using dynamic SQL.
0
sameer2010Commented:
Try this:
use testdb
drop table #a
create table #a(category varchar(10),product varchar(10),dt date,qty int, amt int)
insert into #a values('A','X','01-01-15',2,5),('A','Y','01-07-15',1,4),('A','Y','01-14-15',2,6),('B','X','01-01-15',2,5)

declare @str varchar(max)

select @str='select substring(t1.catprod,1,charindex(''||'',t1.catprod,1)-1) as category,'+ 'substring(t1.catprod,charindex(''||'',t1.catprod,1)+2,len(t1.catprod)) as prod' +
(
select ',t1.['+cast([number] as varchar(2))+'] as week'+cast([number] as varchar(2))+'amt,t2.['+cast([number] as varchar(2))+'] as week' + cast([number] as varchar(2)) + 'qty' from master.dbo.spt_values where type='P' and number between 1 and 52
for xml path('')
) + 

' from
(select * 
from 
(
  select category+''||''+product as catprod, cast(datepart(wk,dt) as varchar(5)) weekofdt, amt  from #a
) src
pivot
(
  avg(amt)
  for weekofdt in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[48],[49],[50],[51],[52])
) as piv

) t1
inner join
(select *
from 
(
  select category+''||''+product as catprod, cast(datepart(wk,dt) as varchar(5)) weekofdt, qty from #a
) src1
pivot
(
  sum(qty)
  for weekofdt in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31],[32],[33],[34],[35],[36],[37],[38],[39],[40],[41],[42],[43],[44],[45],[46],[47],[48],[49],[50],[51],[52])
) piv
) t2
on t1.catprod = t2.catprod'

exec(@str)

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Angel02Author Commented:
Works like a charm!

I just added this to obtain the total Qty and it's perfect! Thank you!

select @str='select t1.Category,'+ 't1.product, (0' +
(
select '+ ISNULL(t2.['+cast([number] as varchar(2))+'],0) '  
from master.dbo.spt_values where type='P' and number between 1 and 52
for xml path('')
) + ')As TotalSold' +
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Query Syntax

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.