SQL Server:超过5列的动态枢轴

前端之家收集整理的这篇文章主要介绍了SQL Server:超过5列的动态枢轴前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个非常艰难的时刻试图找出如何在具有多个列的sql Server 2008中进行动态枢轴.

我的样品表如下:

  1. ID YEAR TYPE TOTAL VOLUME
  2. DD1 2008 A 1000 10
  3. DD1 2008 B 2000 20
  4. DD1 2008 C 3000 30
  5. DD1 2009 A 4000 40
  6. DD1 2009 B 5000 50
  7. DD1 2009 C 6000 60
  8. DD2 2008 A 7000 70
  9. DD2 2008 B 8000 80
  10. DD2 2008 C 9000 90
  11. DD2 2009 A 10000 100
  12. DD2 2009 B 11000 110
  13. DD2 2009 C 12000 120

我正在尝试如下的枢纽:

  1. ID 2008_A_TOTAL 2008_A_VOLUME 2008_B_TOTAL 2008_B_VOLUME 2008_C_TOTAL 2008_C_VOLUME 2009_A_TOTAL 2009_A_VOLUME 2009_B_TOTAL 2009_B_VOLUME 2009_C_TOTAL 2009_C_VOLUME
  2. DD1 1000 10 2000 20 3000 30 4000 40 5000 50 6000 60
  3. DD2 7000 70 8000 80 9000 90 10000 100 11000 110 12000 120

我的sql Server 2008查询如下创建表:

  1. CREATE TABLE ATM_TRANSACTIONS
  2. (
  3. ID varchar(5),T_YEAR varchar(4),T_TYPE varchar(3),TOTAL int,VOLUME int
  4. );
  5.  
  6. INSERT INTO ATM_TRANSACTIONS
  7. (ID,T_YEAR,T_TYPE,TOTAL,VOLUME)
  8.  
  9. VALUES
  10. ('DD1','2008','A',1000,10),('DD1','B',2000,20),'C',3000,30),'2009',4000,40),5000,50),6000,60),('DD2',7000,70),8000,80),9000,90),10000,100),11000,110),1200,120);

T_Year列可能会在将来更改,但T_TYPE列通常是知道的,所以我不知道我是否可以使用sql Server中的PIVOT函数与动态代码的组合?

我试着按照这里的例子:

http://social.technet.microsoft.com/wiki/contents/articles/17510.t-sql-dynamic-pivot-on-multiple-columns.aspx

但我最终得到了奇怪的结果.

解决方法

为了获得结果,您需要先查看“总量”和“体积”列中的数据,然后再应用PIVOT函数才能获得最终结果.我的建议是首先写一个硬编码版本的查询,然后将其转换为动态sql.

UNPIVOT进程将这些多列转换成行.有几种方法可以使用UNPIVOT,您可以使用UNPIVOT功能,也可以使用CROSS APPLY.不透明数据的代码将类似于:

  1. select id,col = cast(t_year as varchar(4))+'_'+t_type+'_'+col,value
  2. from ATM_TRANSACTIONS t
  3. cross apply
  4. (
  5. select 'total',total union all
  6. select 'volume',volume
  7. ) c (col,value);

这给你的数据格式如下:

  1. +-----+---------------+-------+
  2. | id | col | value |
  3. +-----+---------------+-------+
  4. | DD1 | 2008_A_total | 1000 |
  5. | DD1 | 2008_A_volume | 10 |
  6. | DD1 | 2008_B_total | 2000 |
  7. | DD1 | 2008_B_volume | 20 |
  8. | DD1 | 2008_C_total | 3000 |
  9. | DD1 | 2008_C_volume | 30 |
  10. +-----+---------------+-------+

然后你可以应用PIVOT功能

  1. select ID,[2008_A_total],[2008_A_volume],[2008_B_total],[2008_B_volume],[2008_C_total],[2008_C_volume],[2009_A_total],[2009_A_volume]
  2. from
  3. (
  4. select id,value
  5. from ATM_TRANSACTIONS t
  6. cross apply
  7. (
  8. select 'total',total union all
  9. select 'volume',volume
  10. ) c (col,value)
  11. ) d
  12. pivot
  13. (
  14. max(value)
  15. for col in ([2008_A_total],[2009_A_volume])
  16. ) piv;

现在您具有正确的逻辑,您可以将其转换为动态sql

  1. DECLARE @cols AS NVARCHAR(MAX),@query AS NVARCHAR(MAX)
  2.  
  3. select @cols = STUFF((SELECT ',' + QUOTENAME(cast(t_year as varchar(4))+'_'+t_type+'_'+col)
  4. from ATM_TRANSACTIONS t
  5. cross apply
  6. (
  7. select 'total',1 union all
  8. select 'volume',2
  9. ) c (col,so)
  10. group by col,so,T_YEAR
  11. order by T_YEAR,so
  12. FOR XML PATH(''),TYPE
  13. ).value('.','NVARCHAR(MAX)'),1,'')
  14.  
  15. set @query = 'SELECT id,' + @cols + '
  16. from
  17. (
  18. select id,col = cast(t_year as varchar(4))+''_''+t_type+''_''+col,value
  19. from ATM_TRANSACTIONS t
  20. cross apply
  21. (
  22. select ''total'',total union all
  23. select ''volume'',volume
  24. ) c (col,value)
  25. ) x
  26. pivot
  27. (
  28. max(value)
  29. for col in (' + @cols + ')
  30. ) p '
  31.  
  32. execute sp_executesql @query;

这将给你一个结果:

  1. +-----+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+
  2. | id | 2008_A_total | 2008_A_volume | 2008_B_total | 2008_B_volume | 2008_C_total | 2008_C_volume | 2009_A_total | 2009_A_volume | 2009_B_total | 2009_B_volume | 2009_C_total | 2009_C_volume |
  3. +-----+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+
  4. | DD1 | 1000 | 10 | 2000 | 20 | 3000 | 30 | 4000 | 40 | 5000 | 50 | 6000 | 60 |
  5. | DD2 | 7000 | 70 | 8000 | 80 | 9000 | 90 | 10000 | 100 | 11000 | 110 | 1200 | 120 |
  6. +-----+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+--------------+---------------+

猜你在找的MsSQL相关文章