SQL Server - 将列转换为行

时间:2013-12-17 19:00:39

标签: sql sql-server

我有一个表格,简单的选择发出如下所示

enter image description here

我想写一个select语句来输出如下所示

enter image description here

有人可以帮助我......

2 个答案:

答案 0 :(得分:8)

由于您基本上将当前的SaleIncomeProfit列转换为行,然后将month值移至列,然后您将首先想要取消当前列的显示,然后转动月份。

根据您的SQL Server版本,有几种方法可以取消数据的显示。您可以使用UNPIVOT功能或CROSS APPLY:

select month, type, value
from yourtable
cross apply
(
  select 'Sale', sale union all
  select 'Income', Income union all
  select 'Profit', Profit
) c (type, value)

SQL Fiddle with Demo。这会将您当前的数据转换为:

| MONTH |   TYPE | VALUE |
|-------|--------|-------|
|   Jan |   Sale |   100 |
|   Jan | Income |    50 |
|   Jan | Profit |    10 |
|   Feb |   Sale |    20 |
|   Feb | Income |    40 |

然后您可以使用PIVOT函数将月份转换为列标题。

select type, Jan, Feb, Mar, Apr
from
(
  select month, type, value
  from yourtable
  cross apply
  (
    select 'Sale', sale union all
    select 'Income', Income union all
    select 'Profit', Profit
  ) c (type, value)
) d
pivot
(
  sum(value)
  for month in (Jan, Feb, Mar, Apr)
) piv;

SQL Fiddle with Demo

如果你有未知的月数,那么你可以使用动态SQL:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct N',' + QUOTENAME(Month) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT type, ' + @cols + N' 
            from 
            (
                select month, type, value
                from yourtable
                cross apply
                (
                  select ''Sale'', sale union all
                  select ''Income'', Income union all
                  select ''Profit'', Profit
                ) c (type, value)
            ) x
            pivot 
            (
                sum(value)
                for month in (' + @cols + N')
            ) p '

execute sp_executesql @query;

请参阅SQL Fiddle with Demo

答案 1 :(得分:0)

你可以使用UNPIVOT然后PIVOT
最好的是要查询嵌入式SQL 然后用STUFF函数创建几个月的DISTINCT COLUMS 替换FOR oMonth IN([2013年1月],[2013年2月],[2013年3月],[2013年4月])
  这里核心查询

 SELECT  
*
FROM
(  SELECT      
 oMonth, value,col
 from (
 select DATENAME(month,oDate)   + '-' + CAST(YEAR(  oDate) as varchar) as oMonth,        Sales ,Income,Profit
 FROM            SalesSource 
 )A
unpivot
 (
  value for col in ( Sales ,Income,Profit)
 ) u

 ) as sourceTable
 PIVOT
 (
 sum( value)  
 FOR oMonth IN ([January-2013], [February-2013], [March-2013], [April-2013])
 ) AS PivotTable;