SQL Server Exact Table Transpose

泄露秘密 提交于 2019-12-25 05:03:51

问题


How do you achieve an exact transpose in SQL?

Month | High | Low | Avg
-------------------------
Jan   | 10    | 9   | 9.5
-------------------------
Feb   | 8  |  7   | 7.5
-------------------------
Mar   | 7    | 6   | 6.5
-------------------------

Result

------ Jan | Feb | Mar
--------------------------
High-- 10  | 8   | 7
--------------------------
Low--  9   | 7   | 6
--------------------------
Avg    9.5 | 7.5 | 6.5
--------------------------

回答1:


In order to get the result, you will first have to unpivot the High, Low and Avg columns by turning those into rows. Then you will apply the pivot function to convert the month values into columns. (See: MSDN PIVOT/UNPIVOT docs)

Since you are using SQL Server 2008+, you can use CROSS APPLY and VALUES to unpivot. The code to unpivot is:

select t.month, 
  c.col, 
  c.value
from yourtable t
cross apply
(
  values ('High', high), ('Low', Low), ('Avg', Avg)
) c (col, value)

See SQL Fiddle with Demo. This gives the result in a format that can then be pivoted by month:

| MONTH |  COL | VALUE |
------------------------
|   Jan | High |    10 |
|   Jan |  Low |     9 |
|   Jan |  Avg |   9.5 |
|   Feb | High |     8 |
|   Feb |  Low |     7 |

Once the data is in rows, you apply the pivot function, so the code will be:

select col, Jan, Feb, Mar
from
(
  select t.month, 
    c.col, 
    c.value
  from yourtable t
  cross apply
  (
    values ('High', high), ('Low', Low), ('Avg', Avg)
  ) c (col, value)
) d
pivot
(
  sum(value)
  for month in (Jan, Feb, Mar)
) piv

See SQL Fiddle with Demo. This gives the result:

|  COL | JAN | FEB | MAR |
--------------------------
|  Avg | 9.5 | 7.5 | 6.5 |
| High |  10 |   8 |   7 |
|  Low |   9 |   7 |   6 |

Since you are pivoting month names, I doubt that you need a dynamic SQL version of this but if you had an unknown number of values, then you could use dynamic sql to get the result.




回答2:


Great use for pivot and unpivot:

with t as (
    select 'Jan' as mon, cast(10.0 as float) as high, cast(9.0 as float) as low, cast(9.5 as float) as average union all
    select 'Feb' as mon, 8.0, 7.0, 7.5
   )
select stat, Jan, Feb, Mar
from (select mon, STAT, value
      from t
      unpivot  (value for stat in (high, low, average)) u
     ) t
pivot (max(value) for mon in (Jan, Feb, Mar)) as pt


来源:https://stackoverflow.com/questions/15662382/sql-server-exact-table-transpose

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!