2012-09-15 63 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 

注意,你應該優化,如果你的最後一個例子喜歡它與不同年份的相同月份一起工作。