関数を使用UNPIVOT
してこれを行うことができます。以下のバージョンでは、列名と値を連結していますが、いつでも別々の列として表示できます。
select col+':'+cast(value as varchar(10)) col
from test
unpivot
(
value
for col in (A, B, C, D)
) unpiv
デモで SQL Fiddle を参照してください
既知の数の列がある場合、上記はうまく機能しますが、変換する列が 800 ある場合は、動的 SQL を使用してこれを実行することをお勧めします。
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
set @query
= 'select col+'':''+cast(value as varchar(10)) col
from test
unpivot
(
value
for col in ('+ @colsunpivot +')
) u'
exec(@query)
デモで SQL Fiddle を参照してください
注:UNPIVOT
変換する必要があるすべての列のデータ型を使用する場合、同じでなければなりません。そのため、必要に応じてデータをキャスト/変換する必要がある場合があります。
#1を編集します。すべての列でデータ型が異なり、ピボットを解除する必要があるため、次のコードを使用できます。
最初の部分は、動的にアンピボットする列のリストを取得します。
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
2 番目の部分は同じ列のリストを取得しますが、各列を acast
としてラップしvarchar
ます。
select @colsUnpivotCast = stuff((select ', cast('+quotename(C.name)+' as varchar(50)) as '+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
次に、最終的なクエリは次のようになります。
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@colsUnpivotCast AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
select @colsUnpivotCast = stuff((select ', cast('+quotename(C.name)+' as varchar(50)) as '+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
set @query
= 'select col+'':''+value col
from
(
select '+@colsUnpivotCast+'
from test
) src
unpivot
(
value
for col in ('+ @colsunpivot +')
) u'
exec(@query)
デモで SQL Fiddle を参照してください
このUNPIVOT
関数は、次のように と同じプロセスを実行してUNION ALL
います。
select col+':'+value as col
from
(
select A value, 'A' col
from test
union all
select cast(B as varchar(10)) value, 'B' col
from test
union all
select cast(C as varchar(10)) value, 'C' col
from test
union all
select cast(D as varchar(10)) value, 'D' col
from test
) src
デモで SQL Fiddle を参照してください
すべてのクエリの結果は同じです。
| COL |
----------
| A:1 |
| B:2.00 |
| C:3 |
| D:4 |
編集 #2:使用UNPIVOT
すると、一部のデータが削除される可能性のある null 列が取り除かれます。その場合は、列をラップして値IsNull()
を置き換えます。null
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@colsUnpivotCast AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
select @colsUnpivotCast = stuff((select ', IsNull(cast('+quotename(C.name)+' as varchar(50)), '''') as '+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('test')
for xml path('')), 1, 1, '')
set @query
= 'select col+'':''+value col
from
(
select '+@colsUnpivotCast+'
from test
) src
unpivot
(
value
for col in ('+ @colsunpivot +')
) u'
exec(@query)
デモで SQL Fiddle を参照してください
null 値を置き換えると、次のような結果が得られます。
| COL |
----------
| A:1 |
| B:2.00 |
| C: |
| D:4 |