3

次の表を変換する必要があります

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%    
4

2 に答える 2

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を参照してください

于 2012-09-15T12:57:52.840 に答える
1

これを行う 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

異なる年の同じ月で動作させたい場合は、最後の例を最適化する必要があることに注意してください。

于 2012-09-15T11:40:43.347 に答える