这是我的xml文件
<Detials xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Parents>
<Parent id="1234">
<name>
<firstname>ABC</firstname>
<lastname>XYSX</lastname>
</name>
</Parent>
<Parent id="1235">
<name>
<firstname>TFU</firstname>
<lastname>GHY</lastname>
</name>
</Parent>
</Parents>
<Children>
<Child id="457" Parentid="1234">
<name>
<cfirstname>JOHN</cfirstname>
<clastname>SMITH</clastname>
</name>
</Child>
<Child id="459" Parentid="1235">
<name>
<cfirstname>DAVID</cfirstname>
<clastname>SMITH</clastname>
</name>
</Child>
</Children>
</Detials>
我将它存储在一个表格中(使用批量插入)。
当我这样查询时
SELECT
x.c.value('(./Parents/Parent/@id)[1]', 'nvarchar(4)' ) AS id
FROM
T1 s
CROSS APPLY
s.XMLData.nodes('Detials') AS x(c)
我得到结果
Id
----
1234
当我稍微改变它时
SELECT
x.c.value('@id', 'nvarchar(4)' ) AS id
FROM
T1 s
CROSS APPLY
s.XMLData.nodes('/Detials/Parents/Parent') AS x(c)
我明白了:
Id
----
1234
1235
我只想查询结果如此
Parent_id | firstname | lastname | Child_id | Child_First_name | child_last_name
----------+-----------+----------+----------+------------------+-----------
1234 | ABC | XYSX | 457 | JOHN | SMITH
1235 | TFU | GHY | 459 | DAVID | SMITH
我怎么能在查询中这样做?
在我的结果中我想要完全没有。的行数取决于Parentid
。如果我的xml文件包含6个<parent id>
,那么我的查询应该显示每个父ID的所有6行,并且如果Parentid在<child>
中匹配,也会包含Childid的比较标签
谢谢,Jayendran
答案 0 :(得分:1)
您在正确的轨道上,但这需要在两个结果集Parent / Children
上进行左连接示例强>
Declare @T1 table (ID int,XMLData xml)
Insert Into @T1 values
(1,'<Detials xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Parents><Parent id="1234"><name><firstname>ABC</firstname><lastname>XYSX</lastname></name></Parent><Parent id="1235"><name><firstname>TFU</firstname><lastname>GHY</lastname></name></Parent></Parents><Children><Child id="457" Parentid="1234"><name><cfirstname>JOHN</cfirstname><clastname>SMITH</clastname></name></Child><Child id="459" Parentid="1235"><name><cfirstname>DAVID</cfirstname><clastname>SMITH</clastname></name></Child></Children></Detials>')
Select A.ID
,B.*
From @T1 A
Cross Apply (
Select B1.Parent_id
,B1.First_Name
,B1.Last_Name
,B2.Child_id
,B2.Child_First_name
,B2.child_last_name
From (
Select
Parent_id = x.c.value('@id', 'nvarchar(4)' )
,First_Name = x.c.value('(name/firstname)[1]','varchar(50)')
,Last_Name = x.c.value('(name/lastname)[1]','varchar(50)')
From @T1 s
Cross Apply s.XMLData.nodes('/Detials/Parents/Parent') AS x(c)
) B1
Left Join (
Select
pt_id = x.c.value('@Parentid', 'nvarchar(4)' )
,Child_id = x.c.value('@id', 'nvarchar(4)' )
,Child_First_name = x.c.value('(name/cfirstname)[1]','varchar(50)')
,child_last_name = x.c.value('(name/clastname)[1]','varchar(50)')
From @T1 s
Cross Apply s.XMLData.nodes('/Detials/Children/Child ') AS x(c)
) B2
on B1.Parent_id = B2.pt_id
) B
<强>返回强>
答案 1 :(得分:1)
您可以使用以下解决方案:
WITH ParsedXml
AS (
SELECT [type] = y.XmlCol.value('local-name(.)', 'NVARCHAR(128)'),
id = y.XmlCol.value('(@id)[1]', 'INT'),
fname = COALESCE( y.XmlCol.value('(name/firstname)[1]', 'NVARCHAR(100)'), y.XmlCol.value('(name/cfirstname)[1]', 'NVARCHAR(100)') ),
lname = COALESCE( y.XmlCol.value('(name/lastname)[1]', 'NVARCHAR(100)'), y.XmlCol.value('(name/clastname)[1]', 'NVARCHAR(100)') ),
Parentid = y.XmlCol.value('(@Parentid)[1]', 'INT')
FROM @x.nodes('*:Detials/*/*') y(XmlCol)
)
SELECT *
FROM ParsedXml AS p/*arent*/ LEFT JOIN ParsedXml AS c/*hild*/ ON c.[type] = 'Child' AND p.id = c.Parentid
WHERE p.[type] = 'Parent'
<强> Demo 强>
或者这个:
SELECT p.*,
c_id = c.XmlCol.value('(@id)[1]', 'INT'),
c_fname = c.XmlCol.value('(name/cfirstname)[1]', 'NVARCHAR(100)'),
c_lname = c.XmlCol.value('(name/clastname)[1]', 'NVARCHAR(100)')
FROM (
SELECT p_id = y.XmlCol.value('(@id)[1]', 'INT'),
p_fname = y.XmlCol.value('(name/firstname)[1]', 'NVARCHAR(100)'),
p_lname = y.XmlCol.value('(name/lastname)[1]', 'NVARCHAR(100)')
FROM @x.nodes('*:Detials/Parents/Parent') y(XmlCol)
) AS p OUTER APPLY @x.nodes('*:Detials/Children/Child[@Parentid eq sql:column("p_id")]') c(XmlCol)
<强> Demo 强>
答案 2 :(得分:0)
我会一次性解决这个问题:
SELECT Parent.ID
,p.value('(name/firstname/text())[1]','nvarchar(max)')
,p.value('(name/lastname/text())[1]','nvarchar(max)')
,c.value('@id','int')
,c.value('(name/cfirstname/text())[1]','nvarchar(max)')
,c.value('(name/clastname/text())[1]','nvarchar(max)')
FROM @xml.nodes('/Detials/Parents/Parent') AS A(p)
OUTER APPLY (SELECT p.value('@id','int')) AS Parent(ID)
OUTER APPLY @xml.nodes('/Detials/Children/Child[@Parentid=sql:column("Parent.ID")]') AS B(c);
诀窍是,通过Parentid
将APPLY
读入名为的列中。此值可用作谓词,以通过sql:column()
获取子项。