我在MSSQL表的一列中有此XML
<QueryXMLData>
<main ShowAllPhoneNumbers="yes">
<C ID="5753768" HID="1" Name="Michael" SSN="xxxxxxxxxxx" PayType="" Status="Active" StatusID="1">
<S ID="5483911" HID="3" Name="Ethan" SSN="xxxxxxxxxxx" CType="Subscription" TPID="21456" TPName="Outside" TPShortName="Out" Status="Active" StatusID="P" D="Y" Checked="yes" Found="yes">
<TPIDs>
<Phone TP="1122334455" />
</TPIDs>
</S>
</C>
<C ID="5670554" HID="1" Name="Susan" SSN="xxxxxxxxxxx" PayType="" Status="Active" StatusID="1">
<S ID="5297452" HID="3" Name="Johnathan" SSN="xxxxxxxxxxx" CType="Outbound" TPID="110" TPName="Out" TPShortName="Inside" Status="Active" StatusID="1" D="Y" Checked="yes" Found="yes">
<TPIDs>
<Phone TP="3344556677" />
</TPIDs>
</S>
<S ID="5297426" HID="3" Name="Brad" SSN="xxxxxxxxxxx" CType="Outbound" TPID="110" TPName="Out" TPShortName="Inside" Status="Active" StatusID="1" D="Y" Checked="yes" Found="yes">
<TPIDs>
<Phone TP="5566778899" />
</TPIDs>
</S>
</C>
</main>
</QueryXMLData>
我希望它返回这些列:
Customer Name Subscriber Name TPID Phone TP
--------------------------------------------------------------
Michael Ethan 21456 1122334455
Susan Johnathan 110 3344556677
Susan Brad 110 5566778899
我尝试过
SELECT value.value('(QueryXMLData/main/C/@SSN)[1]', 'varchar(50)') AS Customer1,
value.value('(QueryXMLData/main/C/S/@SSN)[1]', 'varchar(50)') AS Subb1
from #tmp
但是我希望它遍历每个值,而不是插入应该从中提取的那一行。
答案 0 :(得分:2)
也许这会有所帮助
Select CustName = x1.value('@Name','varchar(150)')
,SubsName = x2.value('@Name','varchar(150)')
,TPID = x2.value('@TPID','varchar(150)')
,PhoneTP = x2.value('TPIDs[1]/Phone[1]/@TP','varchar(150)')
From @XML.nodes('/QueryXMLData/main/*') lv1 (x1)
Cross Apply x1.nodes('*') lvl2 (x2)
返回
CustName SubsName TPID PhoneTP
Michael Ethan 21456 1122334455
Susan Johnathan 110 3344556677
Susan Brad 110 5566778899
现在,如果您的数据在表中...让我们假设一个名为XMLData的列
示例
Select A.ID
,B.*
From YourTable A
Cross Apply (
Select CustName = x1.value('@Name','varchar(150)')
,SubsName = x2.value('@Name','varchar(150)')
,TPID = x2.value('@TPID','varchar(150)')
,PhoneTP = x2.value('TPIDs[1]/Phone[1]/@TP','varchar(150)')
From XMLData.nodes('/QueryXMLData/main/*') lv1 (x1)
Cross Apply x1.nodes('*') lvl2 (x2)
) B
答案 1 :(得分:2)
另一种给猫皮的方法...
SELECT
n.value('../@Name', 'varchar(50)'),
n.value('@Name', 'varchar(50)'),
n.value('@TPID', 'varchar(50)'),
n.value('(TPIDs/Phone/@TP)[1]', 'varchar(50)')
from #tmp
CROSS APPLY value.nodes('QueryXMLData/main/C/S') n(n)