Question

I am using SQLServer2008. In Stored Procedure, I have calculate some amount and store in @tmp table and then get data from @tmp table.

SELECT  t.BrokerCode,
        t.PlanYear ,
        t.PlanName ,
        SUM(Fresh) AS 'Fresh' ,
FROM    @tmp AS t
GROUP BY t.PlanYear ,
         t.PlanName ,
         t.CscName ,
         t.BrokerCode

This give me Result like :

------------------------------------------------- 
 BrokerCode | PlanYear | PlanName |    Fresh    
-------------------------------------------------
    106     |    3     |   SLP    |      0.00   
    106     |    3     |   MLP    |   1140.00   
    106     |    5     |   MLP    |    570.00   
    205     |    4     |   SLP    |    450.00   

Now I would like to display data as :

----------------------------------------------------------
            |        SLP           |          MLP         |
 ---------------------------------------------------------
 BrokerCode |     3     |    4     |     3    |     5     |
 ----------------------------------------------------------
    106     |    0.00   |   0.00   |  1140.00 |  570.00   |
    205     |    0.00   | 450.00   |     0.00 |    0.00   |

I heared about Pivot query but i don't have much knowledge of Pivot query but still i tried using below query

SELECT *
FROM
(
    SELECT [PlanYear], [BrokerCode], [Fresh] 
    FROM @tmp
) AS source
PIVOT
(
   sum([Fresh])
   FOR [PlanYear] IN ([3], [4], [5])
) as pvt

so it gives me the result :

 ----------------------------------------------
 BrokerCode |     3     |    4     |     5    |
 ----------------------------------------------
    106     | 1140.00   |   0.00   |  570.00  |
    205     |    0.00   | 450.00   |     0.00 |

But my problem is that PlanYear can be anything.

So How can I do this?. Thanks.

Was it helpful?

Solution

Having two levels of heading (plan name > years) is a display issue, not a query issue. However, you can flatten the header by merging the planname and planyear columns in the PIVOT as follows. The search term for this technique is "dynamic pivot".


SQL Fiddle

create table #tmp (
  BrokerCode int,
  PlanYear int,
  PlanName char(3),
  Fresh decimal(10,4));
insert #tmp select
    106     ,    3     ,   'SLP'    ,     0.00   union all select
    106     ,    3     ,   'MLP'    ,  1140.00   union all select   
    106     ,    5     ,   'MLP'    ,   570.00   union all select
    205     ,    4     ,   'SLP'    ,   450.00;

declare @sql nvarchar(max);
select @sql = isnull(@sql+',','') +
              quotename(PlanName+'-'+right(PlanYear,10))
from (select distinct PlanName from #tmp) a
cross join (select distinct PlanYear from #tmp) b
order by PlanName, PlanYear;

set @sql = '
SELECT *
FROM
(
    SELECT PlanName+''-''+right(PlanYear,10) [PlanYear],
          [BrokerCode], [Fresh] 
    FROM #tmp
) AS source
PIVOT
(
   sum([Fresh])
   FOR [PlanYear] IN ('+@sql+')
) as pvt';

exec(@sql);

Results:

| BROKERCODE |  MLP-3 |  MLP-4 |  MLP-5 |  SLP-3 |  SLP-4 |  SLP-5 |
--------------------------------------------------------------------
|        106 |   1140 | (null) |    570 |      0 | (null) | (null) |
|        205 | (null) | (null) | (null) | (null) |    450 | (null) |

If you really wanted the output at the end of your question, then the below variation will do.

declare @sql nvarchar(max);
select @sql = isnull(@sql+',','') +
              quotename(right(PlanYear,10))
from (select distinct PlanYear from #tmp) b
order by PlanYear;

set @sql = '
SELECT *
FROM
(
    SELECT [PlanYear], [BrokerCode], [Fresh] 
    FROM #tmp
) AS source
PIVOT
(
   sum([Fresh])
   FOR [PlanYear] IN ('+@sql+')
) as pvt';

-----------------------------------------
| BROKERCODE |      3 |      4 |      5 |
-----------------------------------------
|        106 |   1140 | (null) |    570 |
|        205 | (null) |    450 | (null) |
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top