おそらくPIVOT関数で発生している問題の一部は、関数を適用する複数の列があるという事実によるものです. PIVOT 関数を使用する場合は、最初に列 と のピボットを解除することをお勧めPriceAttributeComparator
しPriceAttributeMin
ますPriceAttributeMax
。データのピボットを解除すると、複数の列がなくなり、複数の行が作成され、適切な値すべてにピボットを適用できます。
使用している SQL Server のバージョンを指定しませんでしたが、CROSS APPLY を UNION ALL と共に使用して、列のピボットを解除できます。
select priceid,
col = cast(attributeid as varchar(10))+'_'+ col,
value
from
(
select PriceID,
AttributeID,
comp = cast(PriceAttributeComparator as varchar(10)),
[min] = cast(PriceAttributeMin as varchar(10)),
[max] = cast(PriceAttributeMax as varchar(10))
from PriceAttribute
) d
cross apply
(
select 'comp', comp union all
select 'min', [min] union all
select 'max', [max]
) c (col, value)
デモを参照してください。このプロセスにより、データが次の形式に変換されます。
| PRICEID | COL | VALUE |
-----------------------------
| 2 | 1_comp | 1 |
| 2 | 1_min | S |
| 2 | 1_max | (null) |
| 3 | 1_comp | 1 |
| 3 | 1_min | M |
| 3 | 1_max | (null) |
データが複数の行になったら、PIVOT 関数を の値に適用できますcol
。
select priceid,
[1_comp], [1_min], [1_max], [2_comp], [2_min], [2_max]
from
(
select priceid,
col = cast(attributeid as varchar(10))+'_'+ col,
value
from
(
select PriceID,
AttributeID,
comp = cast(PriceAttributeComparator as varchar(10)),
[min] = cast(PriceAttributeMin as varchar(10)),
[max] = cast(PriceAttributeMax as varchar(10))
from PriceAttribute
) d
cross apply
(
select 'comp', comp union all
select 'min', [min] union all
select 'max', [max]
) c (col, value)
) src
pivot
(
max(value)
for col in ([1_comp], [1_min], [1_max], [2_comp], [2_min], [2_max])
) piv;
SQL Fiddle with Demoを参照してください。
上記のバージョンは、値の数がわかっている場合はうまく機能しますが、値が不明な場合は、動的 SQL を使用して結果を取得する必要があります。
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(cast(attributeid as varchar(10))+'_'+ col)
from
(
select distinct attributeid
from priceattribute
) d
cross apply
(
select 'comp', 1 union all
select 'min', 2 union all
select 'max', 3
) c (col, so)
group by attributeid, col, so
order by attributeid, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT priceid, ' + @cols + '
from
(
select priceid,
col = cast(attributeid as varchar(10))+''_''+ col,
value
from
(
select PriceID,
AttributeID,
comp = cast(PriceAttributeComparator as varchar(10)),
[min] = cast(PriceAttributeMin as varchar(10)),
[max] = cast(PriceAttributeMax as varchar(10))
from PriceAttribute
) d
cross apply
(
select ''comp'', comp union all
select ''min'', [min] union all
select ''max'', [max]
) c (col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query;
SQL Fiddle with Demoを参照してください。これらのソリューションにより、次の結果が得られます。
| PRICEID | 1_COMP | 1_MIN | 1_MAX | 2_COMP | 2_MIN | 2_MAX |
----------------------------------------------------------------
| 2 | 1 | S | (null) | (null) | (null) | (null) |
| 3 | 1 | M | (null) | (null) | (null) | (null) |
| 4 | 1 | L | (null) | (null) | (null) | (null) |
| 5 | 1 | L | (null) | 1 | Black | (null) |