以水平格式显示数据

时间:2013-05-01 11:31:49

标签: sql-server sql-server-2008 pivot dynamic-pivot

我正在使用SQLServer2008。在存储过程中,我计算了一些数量并存储在@tmp表中,然后从@tmp表中获取数据。

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

这给我结果如:

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

现在我想将数据显示为:

----------------------------------------------------------
            |        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   |

我听说过Pivot查询,但我对Pivot查询知之甚少,但我还是尝试使用下面的查询

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

所以它给了我结果:

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

但我的问题是PlanYear可以是任何东西。

那我怎么能这样做?感谢。

1 个答案:

答案 0 :(得分:1)

有两个级别的标题(计划名称>年)是显示问题,而不是查询问题。但是,您可以通过合并PIVOT中的planname和planyear列来展平标题,如下所示。该技术的搜索术语是“动态支点”。

<小时/> 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);

<强>结果:

| 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) |

如果你真的想在问题的最后输出,那么the below variation就可以了。

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) |