このタイプのデータ変換では、関数を使用してから、SQL Server で関数をUNPIVOT
適用する必要があります。PIVOT
これを実行するには 2 つの方法があります。動的 SQL を使用して実行時に値を生成する静的バージョンで値をハードコーディングする方法です。
静的バージョン:
このUNPIVOT
部分は、複数の列からデータを取得し、2 つの行に変換します。unpivot で注意すべき点は、データ型が同じでなければならないということです。そのため、データに対してデータ型変換を実行する必要がある場合があります。:
select [Month], value, col
from
(
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
from yourtable
) src
unpivot
(
value
for col in ([Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm])
) unpiv
デモで SQL Fiddle を参照してください
結果:
| MONTH | VALUE | COL |
-------------------------------------
| January-2011 | 30565 | Affec |
| January-2011 | 34623 | KPI |
| January-2011 | 42003 | Total |
| January-2011 | 82.4 | KPI_% |
| January-2011 | 7380 | Out | ---etc
次に、 を月に適用しますPIVOT
。
select *
from
(
select [Month], value, col
from
(
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
from yourtable
) src
unpivot
(
value
for col in ([Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm])
) unpiv
) src
pivot
(
max(value)
for month in ([January-2011], [February-2011], [March-2011],
[April-2011], [January-2012], [February-2012], [March-2012])
) piv
デモで SQL Fiddle を参照してください
結果:
| COL | JANUARY-2011 | FEBRUARY-2011 | MARCH-2011 | APRIL-2011 | JANUARY-2012 | FEBRUARY-2012 | MARCH-2012 |
------------------------------------------------------------------------------------------------------------------
| Affec | 30565 | 27754 | 22838 | 20235 | 20955 | 19513 | 18778 |
| ftm | 5024 | 4189 | 3282 | 2967 | 3518 | 4185 | 4105 |
| KPI | 34623 | 27757 | 23758 | 21950 | 25915 | 25188 | 25098 |
| KPI_% | 82.4 | 76.1 | 79.3 | 84.7 | 93 | 93.4 | 95.9 |
| Out | 7380 | 8726 | 6193 | 3967 | 1942 | 1774 | 1079 |
| rep_in_10 | 7003 | 5648 | 4394 | 3895 | 4754 | 5768 | 5784 |
| Total | 42003 | 36483 | 29951 | 25917 | 27857 | 26962 | 26177 |
動的バージョン:
上記はうまく機能します。値の数がわかっているが、値が不明な場合は、動的SQLを使用する必要があります。日付の数が不明であるため、動的バージョンが必要になると思います。
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = STUFF((SELECT DISTINCT ','
+ quotename(c.name)
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name not in ('Month')
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @cols = STUFF((SELECT ',' + QUOTENAME(DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)))
from yourtable
group by [Month]
order by [Month]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT col,' + @cols + ' from
(
select [Month], value, col
from
(
select DateName(month,[Month]) +''-''+Cast(datepart(year, [month]) as varchar(4)) Month,
[Affec], [KPI], [Total], [KPI_%], [Out], [rep_in_10], [ftm]
from yourtable
) src
unpivot
(
value
for col in ('+@colsunpivot+')
) unpiv
) x
pivot
(
max(value)
for [Month] in (' + @cols + ')
) p '
execute(@query)
デモで SQL Fiddle を参照してください
結果は動的バージョンと同じになります。
集約を使用した UNION ALL/CASE:
UNPIVOT
最後に、またはPIVOT
関数のいずれにもアクセスできない場合は、 を使用してピボットを解除し、 を使用しUNION ALL
て集計関数を使用しCASE
てデータをピボットできます。
select col,
max(case when month='January-2011' then value end) [January-2011],
max(case when month='February-2011' then value end) [February-2011],
max(case when month='March-2011' then value end) [March-2011],
max(case when month='April-2011' then value end) [April-2011],
max(case when month='January-2012' then value end) [January-2012],
max(case when month='February-2012' then value end) [February-2012],
max(case when month='March-2012' then value end) [March-2012]
from
(
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[Affec] value,
'Affec' col
from yourtable
union all
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[KPI] value,
'KPI' col
from yourtable
union all
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[Total] value,
'Total' col
from yourtable
union all
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[KPI_%] value,
'KPI_%' col
from yourtable
union all
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[rep_in_10] value,
'rep_in_10' col
from yourtable
union all
select DateName(month,[Month]) +'-'+Cast(datepart(year, [month]) as varchar(4)) Month,
[ftm] value,
'ftm' col
from yourtable
) src
group by col
デモで SQL Fiddle を参照してください