sql >> データベース >  >> RDS >> Sqlserver

動的ピボット解除と列の分割 SQL Server 2012

    UNPIVOT このようなもの:

    WITH Unpivoted AS( SELECT region, lob, columns, value FROM Regions UNPIVOT ( columns FOR value IN([GWP 2013] , [GWP 2014] , [LR 2013] , [LR 2014] , [GWP 2015] ], [LR 2015]) ) AS u) SELECT region, lob, columns, CAST(CASE WHEN value LIKE 'GWP%' THEN REPLACE(value,'GWP ', '') WHEN value LIKE 'LR%' THEN REPLACE( value,'LR ', '') END AS INT) AS Year, CASE WHEN value LIKE 'GWP%' THEN 'GWP' WHEN value LIKE 'LR%' THEN 'LR' END AS MetricsFROM Unpivoted; 

    そしてもちろん、列を手動でリストすることを避けるために動的に実行し、動的に実行する必要があります:

    DECLARE @cols AS NVARCHAR(MAX);DECLARE @query AS NVARCHAR(MAX);select @cols =STUFF((個別の ',' + QUOTENAME(column_name) FROM information_schema.columns WHERE table_name ='Regions ' AND COLUMN_NAME <> 'Region' AND COLUMN_NAME <> 'LOB' FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') , 1, 1, '');SELECT @ query ='WITH Unpivoted AS ( SELECT region, lob, columns, value FROM Regions UNPIVOT ( columns FOR value IN('+ @cols + ') ) AS u ) SELECT region, lob, columns, CAST(CASE WHEN value LIKE '' GWP%'' THEN REPLACE(値,''GWP '', '''') WHEN value LIKE ''LR%'' THEN REPLACE(value,''LR '', '''') END AS INT) AS Year, CASE WHEN value LIKE ''GWP%'' THEN '' GWP'' WHEN value LIKE ''LR%'' THEN ''LR'' END AS Metrics FROM Unpivoted';EXECUTE(@query); 

    これは、次の場合にうまく機能するはずです:

    • すべての列 [GWP 2013] 、[GWP 2014] 、[LR 2013] 、[LR 2014] 、[GWP 2015]、[LR 2015]、...など は同じ形式です (GWP または LR、スペース、年、および
    • <リ>

      すべての列は同じデータ型 int です または小数。データ型が同じでない場合は、unpivot を実行する前に、それらすべてを 1 つのデータ型にキャストする必要があります。 そうしないと、エラーが発生します。

      <リ>

      SQL Fiddle のデモ

    これにより以下が得られます:

    <プレ>|地域 |ロブ |コラム |年 | 年 |メトリック ||--------|---------|----------|------|---------| | |北 | 北 |労働者 | 労働者38902.5 | 2013年 | || GWP ||北 | 北 |労働者 | 労働者37972404 | 2014年 | || GWP ||北 | 北 |労働者 | 労働者70 | 2015年 | || GWP ||北 | 北 |労働者 | 労働者89 | 2013年 | LR ||北 | 北 |労働者 | 労働者82 | 2014年 | LR ||北 | 北 |労働者 | 労働者80 | 2015年 | LR |

    更新:

    FOR XML PATH('') .. すべての値のリストを 1 つの文字列に連結するには、SQL Server でこれを回避する必要があります。 @cols の値 文字列になります:[GWP 2013], [GWP 2014], ... .

    フィールドのデータ型が異なる場合は、UNPVOT を実行する前に、アンカー クエリでピボット解除されるすべての列をキャストする必要があります。 このように:

    SELECT @query ='WITH Unpivoted AS ( SELECT region, lob, columns, value FROM ( SELECT region, lob, CAST([GWP 2013] AS DECIMAL(10,2)) AS [GWP 2013], CAST([GWP 2014] AS DECIMAL(10,2)) AS [GWP 2014], ... etc FROM Regions ) AS t UNPIVOT ( columns FOR value IN('+ @cols + ') ) AS u ) SELECT region,ロブ、列、CAST(CASE WHEN 値 LIKE ''GWP%'' THEN REPLACE(値,''GWP '', '''') WHEN 値 LIKE ''LR%'' THEN REPLACE(値,''LR ' ', '''') END AS INT) AS 年、C ASE WHEN value LIKE ''GWP%'' THEN ''GWP'' WHEN value LIKE ''LR%'' THEN ''LR'' END AS Metrics FROM Unpivoted'; 

    すべての列のキャストを手動で記述するのが難しい場合は、動的に生成して代わりに追加できます。例:

    DECLARE @colsCasted AS NVARCHAR(MAX);select @colsCasted =STUFF((個別の ',' + 'CAST(' + QUOTENAME(column_name) + 'AS DECIMAL(10,2)) AS ' + QUOTENAME(column_name) FROM information_schema.columns WHERE table_name ='Regions' AND COLUMN_NAME <> 'Region' AND COLUMN_NAME <> 'LOB' FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX) ') , 1, 1, ''); 

    次に、動的クエリでその値を追加します:

    SELECT @query ='WITH Unpivoted AS ( SELECT region, lob, columns, value FROM ( SELECT region, lob, ' + @colsCasted + ' FROM Regions ) AS t UNPIVOT ( columns FOR value IN('+ @cols + ') ) AS u ) SELECT region, lob, columns, CAST(CASE WHEN value LIKE ''GWP%'' THEN REPLACE(value,''GWP '', '''') WHEN value LIKE ''LR %'' THEN REPLACE(value,''LR '', '''') END AS INT) AS Year, CASE WHEN value LIKE ''GWP%'' THEN ''GWP'' WHEN value LIKE ''LR%' ' それから''LR'' END AS Metrics FROM Unpivoted'; EXECUTE(@クエリ); 



    1. ブラウザ経由でPDOを使用してMySQLテーブルからCSVとしてデータを保存する

    2. 列番号を使用してMySQLのテーブルから列を削除する方法

    3. PostgreSQL:ST_GeomFromText(unknown)が存在しません

    4. OracleでQuarterFromDateを取得するにはどうすればよいですか?