4

次のテーブルがあるとします。

Create table test(a int, b int, c int, d int)

次の最初のレコードを取得するには、単に「select * from test」と書くことができます。

あいうえお  
1 2 3 4

しかし、代わりに、次のようにしたい (単一のレコードに対して 4 行):

あ:1  
B: 2  
子:3  
D: 4

誰かがこれを行うのを手伝ってくれますか?

これは、リモート デスクトップ システムで単一のレコードを表示するために必要です。このシステムは非常に遅く、水平スクロールはうまくいかず、800 列あります。したがって、単一のレコードからデータの形式を確認する必要があります。

4

1 に答える 1

11

関数を使用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 |
于 2012-12-12T13:07:09.667 に答える