2012-09-15 64 views
3

我需要下表T-SQL旋转功能

quarter cal_year blue green yellow red 

DEC 2011  +31% 25-30% 22-24% -21% 

MAR 2012  +61% 50-60% 43-49% -42% 

转换成这一点。有没有简单的方法来实现它?

Color DEC  MAR  
blue +31% +61%  
green 25-30% 50-60% 
yellow 22-24% 43-49% 
red  -21% -42%  

回答

3

虽然@ Joro的版本将工作,但我会做这个稍微不同的,因为在这种情况下不需要CTE。

,你知道列PIVOT的静态版本进行改造:

select col, [Mar], [Dec] 
from 
(
    select quarter, val, col 
    from yourtable 
    unpivot 
    (
    val 
    for col in (blue, green, yellow, red) 
)u 
) x 
pivot 
(
    max(val) 
    for quarter in ([Mar], [Dec]) 
) p 

看到SQL Fiddle with Demo

动力版本,其中列在运行时确定:

DECLARE @colsPivot AS NVARCHAR(MAX), 
    @colsUnpivot as NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

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

select @colsUnpivot = stuff((select ','+quotename(C.name) 
     from sys.columns as C 
     where C.object_id = object_id('yourtable') and 
       C.name not in ('Quarter', 'cal_year') 
     for xml path('')), 1, 1, '') 

set @query 
    = 'select * 
     from 
     (
     select quarter, val, col 
     from yourtable 
     unpivot 
     (
      val 
      for col in ('+ @colsunpivot +') 
     ) u 
    ) x1 
     pivot 
     (
     max(val) 
     for quarter in ('+ @colspivot +') 
    ) p' 

exec(@query) 

SQL Fiddle with Demo

如果你只有几列,那么你也可以用CASE语句做到这一点,一个UNION ALL

select col, 
    max(case when quarter = 'MAR' then val end) MAR, 
    max(case when quarter = 'DEC' then val end) DEC 
from 
(
    select quarter, val, col 
    from 
    (
    select quarter, blue as val, 'blue' as col 
    from yourtable 
    union all 
    select quarter, green as val, 'green' as col 
    from yourtable 
    union all 
    select quarter, yellow as val, 'yellow' as col 
    from yourtable 
    union all 
    select quarter, red as val, 'red' as col 
    from yourtable 
) u 
) x 
group by col 

看到SQL Fiddle with Demo

1

下面是做到这一点的一种方法:

DECLARE @SourceTable TABLE 
(
    [Quarter] NVARCHAR(20), 
    [cal_year] BIGINT, 
    [blue] NVARCHAR(20), 
    [green] NVARCHAR(20), 
    [yellow] NVARCHAR(20), 
    [red] NVARCHAR(20) 
) 

INSERT INTO @SourceTable ([Quarter],[cal_year],[blue],[green],[yellow],[red]) 
VALUES ('DEC',2011,'+31%','25-30%','22-24%','-21%') 
     ,('MAR',2012,'+61%','50-60%','43-49%','-42%') 


;WITH CTE([Quarter],[Color],[Value]) AS 
(
    SELECT [Quarter],[Color],[Value] 
    FROM 
     (
      SELECT [Quarter],[blue],[green],[yellow],[red] 
      FROM @SourceTable 
     ) data 
    UNPIVOT 
    (
     [Value] FOR [Color] IN ([blue],[green],[yellow],[red]) 
    )AS unpvt 
) 
SELECT * 
FROM 
(
    SELECT Color,[Quarter],Value 
    FROM CTE 
)AS src 
PIVOT 
(
    MAX(Value) FOR [Quarter] IN ([MAR],[DEC]) 

) AS pvtTbl 

但是让我们假设你有更多的数据来比较:

CREATE TABLE #SourceTable 
(
    [Quarter] NVARCHAR(20), 
    [cal_year] BIGINT, 
    [blue] NVARCHAR(20), 
    [green] NVARCHAR(20), 
    [yellow] NVARCHAR(20), 
    [red] NVARCHAR(20) 
) 

INSERT INTO #SourceTable ([Quarter],[cal_year],[blue],[green],[yellow],[red]) 
VALUES ('DEC',2011,'+31%','25-30%','22-24%','-21%') 
     ,('JAN',2012,'+11%','10-20%','13-49%','-12%') 
     ,('FEB',2012,'+31%','25-35%','12-14%','-11%') 
     ,('MAR',2012,'+71%','10-45%','13-59%','-11%') 
     ,('APR',2012,'+11%','15-15%','12-24%','-51%') 
     ,('MAY',2012,'+11%','40-60%','13-39%','-43%') 


DECLARE @DynamicSQLStatement NVARCHAR(MAX) 

SET @DynamicSQLStatement=N';WITH CTE([Quarter],[Color],[Value]) AS 
         (
          SELECT [Quarter],[Color],[Value] 
          FROM 
           (
            SELECT [Quarter],[blue],[green],[yellow],[red] 
            FROM #SourceTable 
           ) data 
          UNPIVOT 
          (
            [Value] FOR [Color] IN ([blue],[green],[yellow],[red]) 
          )AS unpvt 
         ) 
         SELECT * 
         FROM 
         (
          SELECT Color,[Quarter],Value 
          FROM CTE 
         )AS src 
         PIVOT 
         (
          MAX(Value) FOR [Quarter] IN ('+(SELECT SUBSTRING((SELECT '],[' + [Quarter] FROM #SourceTable FOR XML PATH('')),3,200)+']')+') 
         ) AS pvtTbl' 

EXECUTE sp_executesql @DynamicSQLStatement 


DROP TABLE #SourceTable 

注意,你应该优化,如果你的最后一个例子喜欢它与不同年份的相同月份一起工作。