2017-07-07 11 views
2

私はms sql(version 2012)の '複数の列をピボットする'と苦労しています。行から列への値の取得

Iは所望の形状に構造

 
Supplier Nr SupplierName Manager    Service   Type_of_Service  Planned_Turnover  Turnover   TransactionID   Month     
30    Honda  Name    CityService   varchar   100 000    95 000   009000011440114   201701 
50    Honda22  Name    CityService   varchar   200 000    195 000  0090001101144    201701 
30    Honda  Name    CityService   varchar   130 000    115 000  00900111114    201702 
50    Honda22  Name    CityService   varchar   230 000    205 000  001144     201702 

から値を取得したい:私は1つの列に基づいてテーブルを旋回する方法を理解

 
Supplier Nr SupplierName Manager    Service   Type_of_Service  Planned_Turnover 201701  Turnover 201701   TransactionID 201701 Planned_Turnover 201702  Turnover 201702   TransactionID 201702 
    30    Honda  Name    CityService   varchar    100 000      95000    009000011440114   130 000      115 000      00900111114   
    50    Honda22 Name    CityService   varchar    200 000      195000    0090001101144   230 000      205 000      001144 

- 例えば月ごとの列の月に売上高を取得...しかし、複数の値を取得する方法(Planned_TurnoverTurnoverを、隣同士にTransactionID?)ここで

おかげ

+2

GoogleのSQL Serverのピボット。 – jarlh

+0

ありがとう、私はそうから始まった:) – DRastislav

+0

なぜこれが必要なのか説明してください。通常、このような変換はクライアント側で処理する必要があります –

答えて

2

は、一時テーブルを使用する例と動的SQLです2つの日付のピボットが付いています。

create table #tempTable ([Supplier Nr] int, SupplierName varchar(30), Manager varchar(30), [Service] varchar(30), Type_of_Service varchar(30), Planned_Turnover varchar(30), Turnover varchar(30), TransactionID varchar(30), [Month] int); 

insert into #tempTable ([Supplier Nr],SupplierName,Manager,[Service],Type_of_Service,Planned_Turnover,Turnover,TransactionID,[Month]) values 
(30,'Honda','Name','CityService','varchar','100 000','95 000','009000011440114',201701), 
(50,'Honda22','Name','CityService','varchar','200 000','195 000','0090001101144',201701), 
(30,'Honda','Name','CityService','varchar','130 000','115 000','00900111114',201702), 
(50,'Honda22','Name','CityService','varchar','230 000','205 000','001144',201702); 

DECLARE @SQLString varchar(max); 

SET @SQLString = 'select * 
from (
    select [Supplier Nr], SupplierName, Manager, [Service], Type_of_Service, concat(''Planned_Turnover '',[Month]) as Title, Planned_Turnover as Value 
    from #tempTable where [Month] in (@Date1, @Date2) 
    union all 
    select [Supplier Nr], SupplierName, Manager, [Service], Type_of_Service, concat(''Turnover '',[Month]) as Title, Turnover as Value 
    from #tempTable where [Month] in (@Date1, @Date2) 
    union all 
    select [Supplier Nr], SupplierName, Manager, [Service], Type_of_Service, concat(''TransactionID '',[Month]) as Title, TransactionID as Value 
    from #tempTable where [Month] in (@Date1, @Date2) 
) q 
PIVOT (MAX(Value) FOR Title IN 
([Planned_Turnover @Date1],[Turnover @Date1],[TransactionID @Date1],[Planned_Turnover @Date2],[Turnover @Date2],[TransactionID @Date2]) 
) pvt'; 

declare @Date1 varchar(6) = '201701'; 
declare @Date2 varchar(6) = '201702'; 

SET @SQLString = replace(replace(@SQLString,'@Date1',@Date1),'@Date2',@Date2); 

exec (@SQLString); 

これは2ヶ月に制限されています。それが数ヶ月間の範囲だった場合は、ピボットフィールドのvarcharを計算して@SQLStringで使用する方が良いでしょう。
例コード:

declare @Date1 varchar(6) = '201712'; 
declare @Date2 varchar(6) = '201802'; 

declare @PivotFields varchar(max); 
with cte as (
    select convert(date,concat(@Date1,'01')) as dt 
    union all 
    select dateadd(month,1,dt) from cte where dt < convert(date,concat(@Date2,'01')) 
) 
select @PivotFields = concat(@PivotFields+', ',quotename(word+' '+FORMAT(dt,'yyyyMM'))) 
from cte cross join (values (1,'Planned_Turnover'),(2,'Turnover'),(3,'TransactionID')) words(wordid, word) 
order by dt, wordid; 

-- result: @PivotFields="[Planned_Turnover 201712], [Turnover 201712], [TransactionID 201712], [Planned_Turnover 201801], [Turnover 201801], [TransactionID 201801], [Planned_Turnover 201802], [Turnover 201802], [TransactionID 201802]" 
+0

ダイナミックSQLを好むなら、 'exec'の代わりに' sp_executesql'をパラメータ化するのが良いです –

+0

@MikhailLobanovもっと安全だと思いますが、それらの日付はおそらくユーザー入力ではないでしょう、varchar(6)にコードを注入する危険はありません。そして私はそれを試しましたが、そのメソッドはPIVOTフィールドの変数を置き換えません。とにかく交換が必要なので、パラメータを使用すると、私のゴルフコードの本能が損なわれます。 – LukStorms

関連する問題