2

私は次のようなSQLServerからの結果セットを持っています:

Zone        M1      M2  M3  M4  M5  M6  M7
NORTH       6233    17743   2   6233    6717    7369    7369
SOUTH       12440   20017   7   8057    9724    13418   13418
WEST        33736   30532   5   2184    2056    1944    1944
EAST        3944    14584   2   728     953     970     970
CENTRAL     6233    3636    2   6233    6717    6825    6825

しかし、私はそれを次のように望んでいました:

M       NORTH   SOUTH   WEST    EAST    CENTRAL
M1      6233    12440   33736   3944    6233
M2      17743   20017   30532   14584   3636
M3      2       7       5       2       2
M4      ....

これを行う方法?

または、この形式で取得するにはどうすればよいですか。

Zone    M   Value
EAST    M1  6322
WEST    M1  27387
EAST    M2  2345
....
4

1 に答える 1

3

結果を得るために必要なことはUNPIVOT、関数とPIVOT関数の両方を実装する2段階のプロセスです。

最初のステップはUNPIVOTデータです。これにより、複数の列、、M1などM2が取得され、値と列名を持つ2つの列に変換されます。

select zone, value, col
from data
unpivot
(
  value
  for col in ([M1], [M2], [M3], 
              [M4], [M5], [M6], [M7])
) unpiv;

SQL FiddlewithDemoを参照してください

実行したら、を列にUNPIVOT適用できます。PIVOTZone

select *
from
(
  select zone, value, col
  from data
  unpivot
  (
    value
    for col in ([M1], [M2], [M3], 
                [M4], [M5], [M6], [M7])
  ) unpiv
) src
pivot
(
  sum(value)
  for zone in ([North], [South], [West], [East], [Central])
) piv;

SQL FiddlewithDemoを参照してください

PIVOTこれで、 and関数にアクセスできない場合は、 forと集計関数をUNPIVOT使用して同じことを実行し、 :を複製できます。UNION ALLUNPIVOTCASEPIVOT

select col,
  sum(case when zone='North' then value end) North,
  sum(case when zone='South' then value end) South,
  sum(case when zone='West' then value end) West,
  sum(case when zone='East' then value end) East,
  sum(case when zone='Central' then value end) Central
from
(
  select zone, M1 value, 'M1' col
  from data
  union all
  select zone, M2 value, 'M2' col
  from data
  union all
  select zone, M3 value, 'M3' col
  from data
  union all
  select zone, M4 value, 'M4' col
  from data
  union all
  select zone, M5 value, 'M5' col
  from data
  union all
  select zone, M6 value, 'M6' col
  from data
  union all
  select zone, M7 value, 'M7' col
  from data
) un
group by col

デモ付きのSQLフィドルを参照してください

最後に、ピボット解除またはピボットする列の数が不明な場合は、次の動的バージョンを使用できます。

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

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

select @colsPivot = STUFF((SELECT  distinct ',' 
                      + quotename(Zone)
                    from data
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select *
     from
     (
        select zone, value, col
        from data
        unpivot
        (
          value
          for col in ('+ @colsunpivot +')
        ) u
      ) unpiv
      pivot
      (
        max(value)
        for zone in ('+ @colspivot +')
      ) p'

exec(@query)

SQL FiddlewithDemoを参照してください

すべてのバージョンで同じ結果が得られます。

結果:

| COL | CENTRAL |  EAST | NORTH | SOUTH |  WEST |
-------------------------------------------------
|  M1 |    6233 |  3944 |  6233 | 12440 | 33736 |
|  M2 |    3636 | 14584 | 17743 | 20017 | 30532 |
|  M3 |       2 |     2 |     2 |     7 |     5 |
|  M4 |    6233 |   728 |  6233 |  8057 |  2184 |
|  M5 |    6717 |   953 |  6717 |  9724 |  2056 |
|  M6 |    6825 |   970 |  7369 | 13418 |  1944 |
|  M7 |    6825 |   970 |  7369 | 13418 |  1944 |
于 2012-11-28T14:36:25.980 に答える