Thursday, February 16, 2012

Cross Tab Query

Hi,

I need some help on crosstab query. I have tried the examles, but somehow, not able to find a right solution.

Any help will be appreciated.

thx.

Josh

Table Structure>

Brand Product Line Jan Feb Mar Total A Chocolate Volume 500 200 100 800 B FizzDrink Volume 250 300 200 750 A Chocolate Volume 230 100 120 450 A Chocolate Revenue 2,000 600 350 2,950 B FizzDrink Revenue 1,000 700 250 1,950 A Chocolate Revenue 800 400 550 1,750 A Chocolate AvgEarningPerProduct 4.00 3.00 3.50 3.69 B FizzDrink AvgEarningPerProduct 4.00 2.33 1.25 2.60 A Chocolate AvgEarningPerProduct 3.48 4.00 4.58 3.89

How the resultset should look like>

Brand Product Volume Revenue AvgEarningPerProduct Month A Chocolate 500 2,000 4.00 Jan A Chocolate 200 600 3.00 Feb A Chocolate 100 350 3.50 Mar A Chocolate 800 2,950 3.69 Total A Chocolate 230 800 3.48 Jan A Chocolate 100 400 4.00 Feb A Chocolate 120 550 4.58 Mar A Chocolate 450 1,750 3.89 Total B FizzDrink 250 1,000 4.00 Jan B FizzDrink 300 700 2.33 Feb B FizzDrink 200 250 1.25 Mar B FizzDrink 750 1,950 2.60 Total

select Brand, Product, Volume, Revenue,
AvgEarningPerProduct = Revenue * 1.0 / Volume,
Month
from
(
select Brand, Product,
Volume = case when Line = 'Volume' then Jan else 0 end,
Revenue = case when Line = 'Revenue' then Jan else 0 end,
Month = 'Jan'
from yourtable
union all
select Brand, Product,
Volume = case when Line = 'Volume' then Feb else 0 end,
Revenue = case when Line = 'Revenue' then Feb else 0 end,
Month = 'Feb'
from yourtable
union all
select Brand, Product,
Volume = case when Line = 'Volume' then Mar else 0 end,
Revenue = case when Line = 'Revenue' then Mar else 0 end,
Month = 'Mar'
from yourtable
)a|||

Hi Josh,

I'm not clear on having how you'd differentiate the multiple entries (I just added them together and recalculated average earnings):

Code Snippet

SELECT

Brand

, Product

, Volume

, Revenue

, Cast(Revenue*1./Volume As Decimal(5,2)) As AvgEarningPerProduct

, MonthName

FROM (

SELECT

Brand

, Product

, Sum(Case When Line = 'Volume' Then

Case MonthName

When 'jan' Then jan

When 'feb' Then feb

When 'mar' Then mar

When 'total' Then total

End

End

) Volume

, Sum(Case When line = 'Revenue' then

Case MonthName

When 'jan' Then jan

When 'feb' Then feb

When 'mar' Then mar

When 'total' Then total

End

End

) Revenue

, MonthName

, MonthNumber

FROM #data, (

SELECT 1 MonthNumber, 'Jan' MonthName UNION ALL

SELECT 2, 'Feb' UNION ALL

SELECT 3, 'Mar' UNION ALL

SELECT 13, 'Total') MonthData

GROUP BY Brand, Product, MonthName, MonthNumber

) Data

ORDER BY Brand, Product, MonthNumber;

Jamie

|||

Hi Tan,

Thanks for your help. The query now works perfect. The downside is performance. As I have 20 columns as the one i mentioned in example (Volume, Revenue etc.) and 12 months, it takes some time ro return the results.

BTW, there is aone small problem. Now when I pull the data in reports the month get sorted alphabeticall i.e. April onwards.

Any suggestion, how I can change that?

thanks a lot for your help

Regards

Josh

|||

Josh,

"BTW, there is aone small problem. Now when I pull the data in reports the month get sorted alphabeticall i.e. April onwards.

Any suggestion, how I can change that?"

Yes, create a table that has your Month abbreviations, and a SMALLINT or CHAR(1) sort_key to associate with each month. Include such a table in your JOINs to provide the desired sort order.

Dan

No comments:

Post a Comment