在T-SQL中展平XML结构

时间:2012-10-22 21:46:16

标签: sql-server-2008 tsql

我有以下XML结构

<?xml version="1.0" encoding="utf-8"?>
<DataItems>
    <DataItem>
        <ID>ID1</ID>
        <Metric1>Metric11Value</Metric1>
        <Metric2>Metric12Value</Metric2>
        <OptionalParameters>
           <OptionalParameter>
              <ParameterName>ParamName1</ParameterName>
              <ParameterValue>ParamValue1</ParameterValue>
              <ParameterUnits>ParamUnits1</ParameterUnits>
           <OptionalParamter> 
           <OptionalParameter>
              <ParameterName>ParamName2</ParameterName>
              <ParameterValue>ParamValue2</ParameterValue>
              <ParameterUnits>ParamUnits2</ParameterUnits>
           <OptionalParamter>
           <OptionalParameter>
              <ParameterName>ParamName3</ParameterName>
              <ParameterValue>ParamValue3</ParameterValue>
              <ParameterUnits>ParamUnits3</ParameterUnits>
           <OptionalParamter>
        </OptionalParamters>
    <DataItem>
        <ID>ID2</ID>
        <Metric1>Metric21Value</Metric1>
        <Metric2>Metric22Value</Metric2>
        <OptionalParameters>
           <OptionalParameter>
              <ParameterName>ParamName1</ParameterName>
              <ParameterValue>ParamValue1</ParameterValue>
              <ParameterUnits>ParamUnits1</ParameterUnits>
           <OptionalParamter> 
           <OptionalParameter>
              <ParameterName>ParamName2</ParameterName>
              <ParameterValue>ParamValue2</ParameterValue>
              <ParameterUnits>ParamUnits2</ParameterUnits>
           <OptionalParamter>
           <OptionalParameter>
              <ParameterName>ParamName3</ParameterName>
              <ParameterValue>ParamValue3</ParameterValue>
              <ParameterUnits>ParamUnits3</ParameterUnits>
           <OptionalParamter>
        </OptionalParamters>
    <DataItem>
</DataItems>

我想以一种像

这样的表格的方式来展平它
(ID, Metric1, Metric2, ParamName, ParamValue, ParamUnits)

问题是我不知道如何执行我需要的动态过滤,以消除在内连接或交叉应用期间产生的无效行。所以我基本上总共有(数据项数)^ 2行,包含参数名称,值和单位的所有排列。我想知道如何过滤掉无效的行。

1 个答案:

答案 0 :(得分:0)

我认为你的XML搞砸了。您有一堆打开 XML元素没有匹配的关闭元素。如果您解决了这个问题,那么很容易获得您想要的扁平化输出:

declare @idoc int, @xml varchar(max) = '
<?xml version="1.0" encoding="utf-8"?>
<DataItems>
  <DataItem>
    <ID>ID1</ID>
    <Metric1>Metric11Value</Metric1>
    <Metric2>Metric12Value</Metric2>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName1</ParameterName>
        <ParameterValue>ParamValue1</ParameterValue>
        <ParameterUnits>ParamUnits1</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName2</ParameterName>
        <ParameterValue>ParamValue2</ParameterValue>
        <ParameterUnits>ParamUnits2</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName3</ParameterName>
        <ParameterValue>ParamValue3</ParameterValue>
        <ParameterUnits>ParamUnits3</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
  </DataItem>
  <DataItem>
    <ID>ID2</ID>
    <Metric1>Metric21Value</Metric1>
    <Metric2>Metric22Value</Metric2>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName1</ParameterName>
        <ParameterValue>ParamValue1</ParameterValue>
        <ParameterUnits>ParamUnits1</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName2</ParameterName>
        <ParameterValue>ParamValue2</ParameterValue>
        <ParameterUnits>ParamUnits2</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
    <OptionalParameters>
      <OptionalParameter>
        <ParameterName>ParamName3</ParameterName>
        <ParameterValue>ParamValue3</ParameterValue>
        <ParameterUnits>ParamUnits3</ParameterUnits>
      </OptionalParameter>
    </OptionalParameters>
  </DataItem>
</DataItems>'

exec sp_xml_preparedocument @idoc output, @xml

select *
from   openxml(@idoc, '/DataItems/DataItem/OptionalParameters/OptionalParameter', 1)
with   (
          ID varchar(5) '../../ID', 
          Metric1 varchar(18) '../../Metric1', 
          Metric2 varchar(20) '../../Metric2', 
          ParamName varchar(20) 'ParameterName', 
          ParameterValue varchar(20) 'ParameterValue',
          ParameterUnits varchar(20) 'ParameterUnits'
        )

exec sp_xml_removedocument @idoc
go

返回此内容:

ID    Metric1            Metric2              ParamName            ParameterValue       ParameterUnits
----- ------------------ -------------------- -------------------- -------------------- --------------------
ID1   Metric11Value      Metric12Value        ParamName1           ParamValue1          ParamUnits1
ID1   Metric11Value      Metric12Value        ParamName2           ParamValue2          ParamUnits2
ID1   Metric11Value      Metric12Value        ParamName3           ParamValue3          ParamUnits3
ID2   Metric21Value      Metric22Value        ParamName1           ParamValue1          ParamUnits1
ID2   Metric21Value      Metric22Value        ParamName2           ParamValue2          ParamUnits2
ID2   Metric21Value      Metric22Value        ParamName3           ParamValue3          ParamUnits3