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