2017-11-16 5 views
0

SQL Server 2014 Standard Editionを使用して、XML列名の値をPIVOTすることは可能ですか? ....XML列でPIVOTを実行するにはどうすればよいですか?

<table> 
    <id>{3d2699c4-3159-4e8b-b48c-c2c4c9b5bd77}</id> 
    <rows> 
    <row> 
     <columns> 
     <column name="DESC" value="DACS" type="System.String" /> 
     <column name="ec_amount" value="5000" type="System.Decimal" /> 
     <column name="ec_exrate" value="1" type="System.Decimal" /> 
     <column name="ec_total" value="5000.00" type="System.Decimal" /> 
     <column name="ItemNo" value="PVT-C30" type="System.String" /> 
     <column name="UOM" value="EA" type="System.String" /> 
     <column name="DefaultKey" value="1" type="System.Int32" /><----THIS IS THE COLUMN ON WHICH I WOULD LIKE TO PIVOT 
     </columns> 
    </row> 
    <row> 
     <columns> 
     <column name="DESC" value="DACS" type="System.String" /> 
     <column name="ec_amount" value="1500" type="System.Decimal" /> 
     <column name="ec_exrate" value="5" type="System.Decimal" /> 
     <column name="ec_total" value="7500.00" type="System.Decimal" /> 
     <column name="ItemNo" value="PVT-C30" type="System.String" /> 
     <column name="UOM" value="EA" type="System.String" /> 
     <column name="DefaultKey" value="2" type="System.Int32" /> 
     </columns> 
    </row> 
    </rows> 
    <key>DefaultKey</key> 
    <total>12500.00</total> 
    <data /> 
    <parameters /> 
</table> 

をし、これらの結果を作成:最終的に私はこれを取るしたいのですが、私はスタックオーバーフローのサイトを検索した、すべての私は、全体でこれらの2つのポストが来た

DefaultKey DESC ec_amount ec_exrate ec_total ItemNo  UOM 
1   DACS 5000  1   5000  PVT-C30  EA 
2   DACS 1500  5   7500  PVT-C30  EA 

を近くに来ましたが、彼らは非常にそこに私を得ることはありません:

SQL Pivot using an XML column

How do I Pivot on an XML column's attributes in T-SQL

これは既に解決済みで、私はあまりにも早くあきらめてしまったのではないかと心配しています。

+0

試してみてください。あなたは値を取得する必要があります。 – ZLK

+0

これは、DefaultKeys(ピボットしたいフィールド)がいくつあっても問題ありません。どのようにして「価値を得る」ことができるのか説明できるなら、確かにそれを撃つだろう。 – TheDude

+0

私の前のコメントは気にしないでください。ちょうどPIVOTをするのが最も簡単かもしれません。回答には可能な方法を説明しますが、本質的には、XMLで行を区別するための何かが必要です。 – ZLK

答えて

0

基本的には、XMLの各「行」に行番号を割り当てる必要があります(または、各「行」を区別する他の方法を理解する必要があります)。この約行くことができる方法の一つは、(窓関数とパーティショニングを使って)各「行」からデフォルトのキーを抽出することである:

SELECT * 
FROM 
(
    SELECT Name = C2.X.value('@name', 'varchar(max)'), 
      Val = C2.X.value('@value', 'varchar(max)'), 
      DefaultKey = MAX(CASE WHEN C2.X.value('@name', 'varchar(max)') = 'DefaultKey' THEN C2.X.value('@value', 'varchar(max)') END) OVER(PARTITION BY C1.X) 
    FROM myTable 
    CROSS APPLY myXMLColumn.nodes('table/rows/row/columns') AS C1(X) 
    CROSS APPLY C1.X.nodes('column') AS C2(X) 
) AS T 
PIVOT (MAX(Val) FOR Name IN ([DESC], [ec_amount], [ec_exrate], [ec_total], [ItemNo], [UOM])) AS P; 

DefaultKeyの独特でなかった場合は、行番号またはランクを使用できます代わりに、それぞれ同様の結果にウィンドウ関数は:

SELECT * 
FROM 
(
    SELECT Name = C2.X.value('@name', 'varchar(max)'), 
      Val = C2.X.value('@value', 'varchar(max)'), 
      RowInXML = DENSE_RANK() OVER (ORDER BY C1.X) 
    FROM myTable 
    CROSS APPLY myXMLColumn.nodes('table/rows/row/columns') AS C1(X) 
    CROSS APPLY C1.X.nodes('column') AS C2(X) 
) AS T 
PIVOT (MAX(Val) FOR Name IN ([DefaultKey], [DESC], [ec_amount], [ec_exrate], [ec_total], [ItemNo], [UOM])) AS P; 
+0

ZLKありがとうございます。これは美しく働いた。 Shnugoにもありがとうございましたが、私はすでにPIVOTの構造を持っていたので、私はZLKのソリューション – TheDude

1

旋回させるための必要性無し...私はあなたがここで何を旋回させる必要はないと思う。この

DECLARE @xml XML=N'<table> 
    <id>{3d2699c4-3159-4e8b-b48c-c2c4c9b5bd77}</id> 
    <rows> 
    <row> 
     <columns> 
     <column name="DESC" value="DACS" type="System.String" /> 
     <column name="ec_amount" value="5000" type="System.Decimal" /> 
     <column name="ec_exrate" value="1" type="System.Decimal" /> 
     <column name="ec_total" value="5000.00" type="System.Decimal" /> 
     <column name="ItemNo" value="PVT-C30" type="System.String" /> 
     <column name="UOM" value="EA" type="System.String" /> 
     <column name="DefaultKey" value="1" type="System.Int32" /> 
     </columns> 
    </row> 
    <row> 
     <columns> 
     <column name="DESC" value="DACS" type="System.String" /> 
     <column name="ec_amount" value="1500" type="System.Decimal" /> 
     <column name="ec_exrate" value="5" type="System.Decimal" /> 
     <column name="ec_total" value="7500.00" type="System.Decimal" /> 
     <column name="ItemNo" value="PVT-C30" type="System.String" /> 
     <column name="UOM" value="EA" type="System.String" /> 
     <column name="DefaultKey" value="2" type="System.Int32" /> 
     </columns> 
    </row> 
    </rows> 
    <key>DefaultKey</key> 
    <total>12500.00</total> 
    <data /> 
    <parameters /> 
</table>'; 

SELECT r.value(N'(columns/column[@name="DefaultKey"]/@value)[1]',N'int') AS DefaultKey 
     ,r.value(N'(columns/column[@name="DESC"]/@value)[1]',N'nvarchar(max)') AS [DESC] 
     ,r.value(N'(columns/column[@name="ec_amount"]/@value)[1]',N'decimal(10,4)') AS ec_amount 
     --similar with your other elements 
FROM @xml.nodes(N'/table/rows/row') AS A(r) 
関連する問題