複数の列に存在する属性を集計しようとしているため、 UNPIVOT関数とPIVOT関数の両方を適用する必要があることを示しています。
UNPIVOT は、列の値を取得して行に変換します。アンピボットするコードは次のようになります。
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
SQL Fiddle with Demoを参照してください。product_price
これには、列を varchar に変換するサブクエリがあることがわかります。これは、行に含める列のデータ型が同じでなければならないためです。したがって、これを適切に機能させるには、データ変換を実行する必要がある場合があります。
アンピボットにより、次のような結果が生成されます。
| PRODUCT_ID | HEADER | VALUE |
---------------------------------------
| 141 | product_name | A141 |
| 141 | product_price | 200 |
| 141 | product_weight | 200gm |
データが行に入ったら、PIVOT 関数をproduct_id
列の値に適用できます。
select header, [141], [142], [143], [144]
from
(
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
) d
pivot
(
max(value)
for product_id in ([141], [142], [143], [144])
) piv
SQL Fiddle with Demoを参照してください。これにより、次の結果が得られます。
| HEADER | 141 | 142 | 143 | 144 |
--------------------------------------------------
| product_name | A141 | A142 | A143 | A144 |
| product_price | 200 | 300 | 4000 | 5000 |
| product_weight | 200gm | 300gm | 400gm | 100gm |
上記のバージョンは、列として必要な既知の数のproduct_id
値がある場合にうまく機能します。ただし、番号が不明な場合は、動的 SQL を実装する必要があります。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(product_id)
from tblProduct
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT header, ' + @cols + '
from
(
select product_id, header, value
from
(
select product_id,
product_name,
cast(product_price as varchar(10)) product_price,
product_weight
from tblProduct
) p
unpivot
(
value
for header in (product_name, product_price, product_weight)
) unp
) x
pivot
(
max(value)
for product_id in (' + @cols + ')
) p '
execute(@query)
SQL Fiddle with Demoを参照してください。これにより、静的/ハードコーディングされたバージョンのクエリと同じ結果が生成されます。