2017-05-25 13 views
0

行データを列からデータに変換しない列に変換したいと考えています。私はPivotを使っても正しい解決策は得られないと思います。私のデータがどのように見え、どのように見たいのかを見てください。SQL Serverを使用して行データを列データに変換する

enter image description here

例で返される行数は、時間の経過とともに成長していきます。

私のソリューション: @Trivに基づいて、私は新しい列を作成するには、ランク機能を使用して、データを変換するために、動的ピボットSQLを使用して問題を解決するために管理している、と答えました。

+0

使う代わりに@testTableの、これをチェックアウト、私はあなたが、動的SQLクエリが必要だと思います。 – TriV

+0

申し訳ありませんが、私は非常にSQLに新しく、これを行う方法がわかりません。あなたはこれを行うにはSQLを共有することができますか? – DDougill

+0

あなたのSQLサーバーのバージョン? – TriV

答えて

0

あなたは動的SQLを使用することができます+ PIVOT

CREATE TABLE #SampleData 
(
    AccountNumber int, 
    Product varchar(20), 
    ProductEndDate datetime 
) 

INSERT INTO #SampleData VALUES (1,'Fixed 10','2016-01-01'),(1,'Fixed 11','2016-02-01'),(1,'Fixed 13','2016-03-01'),(1,'Fixed 12','2016-04-01'), 
         (2,'Fixed 10','2016-01-01'),(2,'Fixed 11','2016-02-01'),(2,'Fixed 13','2016-03-01') 

DECLARE @HeaderAll nvarchar(max) 
DECLARE @ColumnPivotProduct nvarchar(max) 
DECLARE @ColumnPivotProductEndDate nvarchar(max) 

;WITH temp AS 
(
    SELECT DISTINCT 
    CONCAT('Product' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductGroup, 
    CONCAT('ProductEndDate' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductEndDateGroup 
    FROM #SampleData sd 
) 
SELECT @HeaderAll = STUFF((SELECT CONCAT(',',t.ProductGroup,'= MAX(',t.ProductGroup, '),', t.ProductEndDateGroup ,'= MAX(', t.ProductEndDateGroup,')') FROM temp t FOR XML PATH('')), 1,1,''), 
    @ColumnPivotProduct = STUFF((SELECT CONCAT(',',t.ProductGroup) FROM temp t FOR XML PATH('')), 1,1,''), 
    @ColumnPivotProductEndDate = STUFF((SELECT CONCAT(',', t.ProductEndDateGroup) FROM temp t FOR XML PATH('')), 1,1,'') 

--SELECT @HeaderAll, @ColumnPivotProduct, @ColumnPivotProductEndDate 


DECLARE @query nvarchar(max) = CONCAT(
     ';WITH temp AS 
     (
      SELECT *, 
      CONCAT(''Product'' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductGroup, 
      CONCAT(''ProductEndDate'' ,row_number() OVER(PARTITION BY sd.AccountNumber ORDER BY sd.Product)) AS ProductEndDateGroup 
      FROM #SampleData sd 
     ) 
     SELECT AccountNumber, ',@HeaderAll,' FROM   
      (
      SELECT t.AccountNumber, t.Product, t.ProductEndDate, t.ProductGroup,t.ProductEndDateGroup FROM temp t 
     ) src 
      PIVOT 
      (
      MIN(Product) FOR ProductGroup IN (',@ColumnPivotProduct,')  
     ) pvt 
      PIVOT 
      (
      MIN(ProductEndDate) FOR ProductEndDateGroup IN (',@ColumnPivotProductEndDate,')  
     ) pvt1 
     GROUP BY AccountNumber   
     ') 

PRINT @query 
exec(@query) 


DROP TABLE #SampleData 

デモへのリンク:http://rextester.com/AEQBZ56634

注:CONCATは、SQLサーバ2012+で下盛です。古いバージョンを使用している場合は、それが動作する文字列

+0

ありがとうTriV、私は同じ解決策を思いついた。 – DDougill

+0

ようこそ。 @ DDougill .... – TriV

0

を連結するため+を使用し、あなたのテーブル名が

declare @temptable varchar(1000) = 'declare @tempTable1 table (', 

@inserStatement varchar(1000) = 'insert into @tempTable1 (', 

@insertValues varchar(1000) = '' 

DECLARE @AcountNumber VARCHAR(50),@Product varchar(40),@ProductEndData varchar(50), @increment int = 0; 

DECLARE db_cursor CURSOR FOR 
select 
Product, 
ProductEndData from @testTable 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @Product, @ProductEndData 

WHILE @@FETCH_STATUS = 0 
BEGIN 
set @increment = @increment+1; 
     SET @temptable += 'Product'+ cast(@increment as varchar) +' varchar(100),' + 'Product' + cast(@increment as varchar) + 'EndDate varchar(100),' ; 
     set @inserStatement += 'Product'+ cast(@increment as varchar) +',' + 'Product' + cast(@increment as varchar) + 'EndDate,'; 

     set @insertValues += '(''' + @Product +''''+ ',' + ''''+ @ProductEndData + '''' + ')'; 


     FETCH NEXT FROM db_cursor INTO @Product, @ProductEndData 

END 

CLOSE db_cursor 
DEALLOCATE db_cursor 

set @temptable = STUFF(@temptable, LEN(@temptable), 1, ')') 
set @inserStatement = STUFF(@inserStatement, LEN(@inserStatement), 1, ')') 
set @insertValues = replace(@insertValues, ')(', ',') 
exec (@temptable + @inserStatement + ' values ' + @insertValues + 'select * from @tempTable1') 
関連する問題