简体   繁体   English

如何在XML列上PIVOT?

[英]How do I PIVOT on an XML column?

Is it possible, using SQL Server 2014 Standard Edition, to PIVOT on the value of an XML column name? 使用SQL Server 2014 Standard Edition,是否可以将XML列名称的值设置为PIVOT? Ultimately I'd like to take this: 最终,我想这样做:

<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>

....and create these results: ...并创建以下结果:

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

I've searched the Stack Overflow site and of everything I came across, these two posts came close, but they don't quite get me there: 我搜索了Stack Overflow网站,发现了所有内容,这两篇文章相距甚远,但它们并不能使我到达那里:

SQL Pivot using an XML column 使用XML列的SQL Pivot

How do I Pivot on an XML column's attributes in T-SQL 如何在T-SQL中透视XML列的属性

My apologies if this has already been addressed and I simply gave up too soon. 我很抱歉,如果这个问题已经解决,我只是放弃太早了。

No need for pivoting... Try this 无需旋转...尝试一下

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)

You essentially need to assign a row number to each "row" of XML (or figure out some other way of distinguishing each "row"). 本质上,您需要为XML的每个“行”分配一个行号(或找出区分每个“行”的其他方式)。 One way you could go about this is by extracting the default key from each "row" (by using a window function and partitioning): 解决此问题的一种方法是从每个“行”中提取默认密钥(通过使用窗口函数和分区):

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;

If DefaultKey weren't unique, you could use a row number or rank window function instead to each a similar result: 如果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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM