0

私が解決しなければならない問題は、多くの動的フィールドを持つ 1 つのテーブルから、他の構造化キー値テーブルへのデータ転送です。最初のテーブルは、別のシステムからのデータ エクスポートから取得され、次の構造を持ちます (任意の列名とデータを含めることができます): [UserID],[FirstName],[LastName],[Email],[How was your day] ,[毎週のニュースレターを受け取りますか],[18 歳以上であることを確認してください] ...

2 番目のテーブルは、データを配置する場所であり、次の構造を持っています: [UserID uniqueidentifier],[QuestionText nvarchar(500)],[Question Answer nvarchar(max)]

テーブルのピボットを解除する方法を示す多くの例を見ましたが、私の問題は、テーブル 1 に含まれる列がわからないことです。どうにかして最初のテーブルを動的にピボット解除できますか?そのため、列が何であっても、キーと値の構造に変換され、データが 2 番目のテーブルにインポートされます。

ご協力をお願いいたします。

4

1 に答える 1

0

列を知らずに、1 つのクエリでピボットまたはアンピボットすることはできません。

権限があると仮定してできることは、クエリを実行sys.columnsしてソース テーブルのフィールド名を取得し、アンピボット クエリを動的に作成することです。

--Source table
create table MyTable (
    id int,
    Field1 nvarchar(10),
    Field2 nvarchar(10),
    Field3 nvarchar(10)
);

insert into MyTable (id, Field1, Field2, Field3) values ( 1, 'aaa', 'bbb', 'ccc' );
insert into MyTable (id, Field1, Field2, Field3) values ( 2, 'eee', 'fff', 'ggg' );
insert into MyTable (id, Field1, Field2, Field3) values ( 3, 'hhh', 'iii', 'jjj' );

--key/value table
create table MyValuesTable (
    id int,
    [field] sysname,
    [value] nvarchar(10)
);



declare @columnString nvarchar(max)

--This recursive CTE examines the source table's columns excluding
--the 'id' column explicitly and builds a string of column names
--like so: '[Field1], [Field2], [Field3]'.

;with columnNames as (
  select column_id, name
  from sys.columns 
  where object_id = object_id('MyTable','U')
    and name <> 'id'
),
columnString (id, string) as (
  select
    2, cast('' as nvarchar(max))
  union all
  select
    b.id + 1, b.string + case when b.string = '' then '' else ', ' end + '[' + a.name + ']'
  from
    columnNames a
    join columnString b on b.id = a.column_id
)
select top 1 @columnString = string from columnString order by id desc

--Now I build a query around the column names which unpivots the source and inserts into the key/value table.
declare @sql nvarchar(max)
set @sql = '
insert MyValuestable
select id, field, value
from
  (select * from MyTable) b
unpivot
  (value for field in (' + @columnString + ')) as unpvt'

--Query's ready to run.
exec (@sql)

select * from MyValuesTable

ストアド プロシージャからソース データを取得する場合は、 を使用OPENROWSETしてデータをテーブルに取得し、そのテーブルの列名を調べることができます。このリンクは、その部分を行う方法を示しています。 https://stackoverflow.com/a/1228165/300242

最後の注意: 一時テーブルを使用する場合は、次のように列名を取得することに注意してくださいtempdb.sys.columns

select column_id, name
from tempdb.sys.columns 
where object_id = object_id('tempdb..#MyTable','U')
于 2015-06-12T04:05:41.173 に答える