简体   繁体   中英

xquery compare 2 xml column for same element name

I have 2 xml columns in my SQL Server database, both with same structure but different data.

Like so:

1st column - <root><Person>1</Person><Person>3</Person><Person>6</Person></root>

2nd column - <root><Person>2</Person><Person>3</Person><Person>6</Person></root>

I need to compare by node name if any of the inner text values are common between these 2 columns. For the above eg., it should return true because person node has 3 and 6 in common.

I tried using xquery. I can compare the node to a specific value but not to another column like so:

select *
from t
where data.Person.exist('/Person[(text()[1]) eq "3"]') = 1

The following query will first use .nodes() to get all <Person> Numbers form the first XML, then use a corellated sub-query to get the second XML's values as a derived table which can be INNER JOIN ed. The result is a set reduced to the common numbers. You can group them by the row's ID column.

DECLARE @tbl TABLE (ID INT IDENTITY, Xml1 XML, Xml2 XML);
INSERT INTO @tbl VALUES
 ('<root><Person>1</Person><Person>3</Person><Person>6</Person></root>'
 ,'<root><Person>2</Person><Person>3</Person><Person>6</Person></root>');

SELECT t1.ID
      ,p1.value('text()[1]','int')
FROM @tbl t1
CROSS APPLY t1.Xml1.nodes('/root/Person') A(p1)
INNER JOIN(SELECT p2.value('text()[1]','int') AS p2_Nmbr 
           FROM @tbl t2 
           WHERE t1.ID=t2.ID
           CROSS APPLY t2.Xml2.nodes('/root/Person') B(p2)) Tbl_p2 ON p1.value('text()[1]','int')=Tbl_p2.p2_Nmbr;

UPDATE

This query will use a CROSS APPLY to combine both XMLs to one. With this combined XML you can run an XQuery first to get a distinct list of all IDs of the first and then check for common values:

SELECT * 
       ,BothXml.query(N'for $p1 in distinct-values(/persons[1]/root[1]/Person/text())
                              for $p2 in distinct-values(/persons[1]/root[2]/Person[text()=$p1]/text())
                              return $p2    
                       ') AS CommonIDs
FROM @tbl t
CROSS APPLY(SELECT t.Xml1 AS [*],t.Xml2 AS [*] FOR XML PATH('persons'),TYPE) A(BothXml);

There will be an empty result if there are no common IDs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM