需要仅选择以“name”和条件检查开头的属性值

时间:2017-01-27 10:30:22

标签: sql-server xml

请在下面的XML数据上建议:

<data>
<x name="name0">val1</x>
<x name="other0">Yes</x>
<x name="name1">val2</x>
<x name="other1">Yes</x>
<x name="name2">val3</x>
<x name="other2">No</x>
<x name="name3">val4</x>
<x name="other3">No</x>
...
...
</data>

只需选择那些以“名称”开头的属性值为0,1,2,3 ...其各自的“其他”值0,1,2,3为“是”...端对端映射在0,1,2,3 ...为“名称”&amp; “其他”基于“是”或“否”

1 个答案:

答案 0 :(得分:1)

这是一个糟糕的设计!

如果您可以控制此XML的创建,那么您应该将其更改为

<data>
  <x val1="SomeName" val2="SomeOtherValue">
</data>

这样做,您就拥有了相应的值。 避免编号的列名!
如果你需要这个,那就这样做

<data>
  <x val1="SomeName" Number="1" val2="SomeOtherValue">
</data>

然而你的问题可以解决:

DECLARE @xml XML=
'<data>
<x name="name0">val1</x>
<x name="other0">Yes</x>
<x name="name1">val2</x>
<x name="other1">Yes</x>
<x name="name2">val3</x>
<x name="other2">No</x>
<x name="name3">val4</x>
<x name="other3">No</x>
</data>';

WITH Shredded AS
(
    SELECT x.value('@name','nvarchar(max)') AS x_name
          ,PATINDEX('%[0-9]%',x.value('@name','nvarchar(max)')) AS PositionFirstNumber
          ,x.value('.','nvarchar(max)') AS x_value
    FROM @xml.nodes('/data/x') AS A(x)
)
,Splitted AS
(
    SELECT LEFT(x_name,PositionFirstNumber-1) AS columnName
          ,SUBSTRING(x_name,PositionFirstNumber,100) AS ColumnIndex
          ,x_value
    FROM Shredded
)
SELECT s1.x_value AS name_value
      ,(SELECT x_value FROM Splitted AS s2 WHERE s2.columnName='other' AND s1.ColumnIndex=s2.ColumnIndex) AS Corresponding_value

FROM Splitted AS s1 WHERE s1.columnName='name'

您可以过滤到任何条件的结果是

val1    Yes
val2    Yes
val3    No
val4    No