使用SQL重复数据查询XML

时间:2014-05-08 14:01:13

标签: sql sql-server xml tsql repeater

我需要协助查询使用T-SQL(2008/2012)重复数据的XML文件。

XML代码如下。它包含一些摘要级别节点(VENDOR_NAME,VENDOR_NUMBER,SUBTOTAL),然后是详细级别行(在NONPO容器节点中),然后是另一组详细信息行(在NONPO2容器节点中)。

<Document ID="11">
  <Version>4.7</Version>
  <LastModifiedInVersion>4.7</LastModifiedInVersion>
  <Controls>
    <Control ID="VENDOR_NAME">
      <Value>CVS</Value>
    </Control>
    <Control ID="VENDOR_NUMBER">
      <Value>1101</Value>
    </Control>
  </Controls>
  <Container ID="NONPO">
    <Header />
    <Row>
      <Control ID="INVOICE_NUMBER">
        <Value>23126</Value>
      </Control>
      <Control ID="INVOICE_DATE">
        <Value>05/13/2014</Value>
      </Control>
      <Container ID="NONPO2">
        <Header />
        <Row>
          <Control ID="DESCRIPTION">
            <Value>Pens</Value>
          </Control>
          <Control ID="AMOUNT">
            <Value>50.32</Value>
          </Control>
        </Row>
        <Row>
          <Control ID="DESCRIPTION">
            <Value>Tape</Value>
          </Control>
          <Control ID="AMOUNT">
            <Value>60.00</Value>
          </Control>
        </Row>
        <Footer>
          <Control ID="INV_SUBTOTAL">
            <Value>110.32</Value>
          </Control>
        </Footer>
      </Container>
    </Row>
    <Row>
      <Control ID="INVOICE_NUMBER">
        <Value>61626</Value>
      </Control>
      <Control ID="INVOICE_DATE">
        <Value>06/01/2014</Value>
      </Control>
      <Container ID="NONPO2">
        <Header />
        <Row>
          <Control ID="DESCRIPTION">
            <Value>Microsoft Office</Value>
          </Control>
          <Control ID="AMOUNT">
            <Value>1600.00</Value>
          </Control>
        </Row>
        <Footer>
          <Control ID="INV_SUBTOTAL">
            <Value>1600.00</Value>
          </Control>
        </Footer>
      </Container>
    </Row>
    <Footer>
      <Control ID="SUBTOTAL">
        <Value>1710.32</Value>
      </Control>
    </Footer>
  </Container>
  <AutoKeys />
</Document>

我想最终得到类似于以下输出的内容:

VENDOR_NAME     VENDOR_NUMBER   INVOICE_NUMBER  INVOICE_DATE    DESCRIPTION         AMOUNT  INV_SUBTOTAL    SUBTOTAL
CVS             1101            23126           5/13/2014       Pens                50.32   110.32          1710.32
CVS             1101            23126           5/13/2014       Tape                60      110.32          1710.32
CVS             1101            61626           6/1/2014        Microsoft Office    1600    1600            1710.32

1 个答案:

答案 0 :(得分:6)

select @XML.value('(/Document/Controls/Control[@ID = "VENDOR_NAME"]/Value/text())[1]', 'nvarchar(100)') as VENDOR_NAME,
       @XML.value('(/Document/Controls/Control[@ID = "VENDOR_NUMBER"]/Value/text())[1]', 'int') as VENDOR_NUMBER,
       R1.X.value('(Control[@ID = "INVOICE_NUMBER"]/Value/text())[1]', 'int') as INVOICE_NUMBER,
       R2.X.value('(Control[@ID = "DESCRIPTION"]/Value/text())[1]', 'nvarchar(max)') as DESCRIPTION,
       R2.X.value('(Control[@ID = "AMOUNT"]/Value/text())[1]', 'nvarchar(max)') as AMOUNT,
       C2.X.value('(Footer/Control[@ID = "INV_SUBTOTAL"]/Value/text())[1]', 'nvarchar(max)') as INV_SUBTOTAL,
       C1.X.value('(Footer/Control[@ID = "SUBTOTAL"]/Value/text())[1]', 'nvarchar(max)') as SUBTOTAL
from @XML.nodes('/Document/Container') as C1(X)
  cross apply C1.X.nodes('Row') as R1(X)
  cross apply R1.X.nodes('Container') as C2(X)
  cross apply C2.X.nodes('Row') as R2(X)

SQL Fiddle