简体   繁体   中英

verify that xml node has a child node with a given value tsql

I have the following tables

A (ID, relatedID, typeId )
B (ID, leftID, leftTypeId)

I want to join the two tables like this

select * from A
inner join B on A.TypeId=B.LeftTypeId and {condition}

where condition should verify id the leftID would match a value from relatedID , where relatedId is a xml column. Eg. relatedID= <Id>1</Id>

Is there a optimal way to do this?

UPDATE relatedID can contain several Ids. Eg Eg. relatedID=<Id>1</Id><Id>2</Id>

You may use

... and A.relatedID.value('(/Id[1]/text())[1]', 'int') = B.leftID

or

... and A.relatedID.exist('(/Id[1]/text())[1] = sql:column("B.leftID")') = 1

Though exist is recommended over value for predicates, depending on whether the XML column is xml-indexed or not and what type of indexes it has, one of the two above may perform better.

upd. for the case when relatedID can contain set of Ids you may try

select ...
from A
    cross apply A.relatedID.nodes('/Id') r(id)
    inner join B on A.TypeId=B.LeftTypeId
        and r.id.value('text()[1]', 'int') = B.leftID

or

select ...
from A
    cross apply A.relatedID.nodes('/Id') r(id)
    inner join B on A.TypeId=B.LeftTypeId
        and r.id.exist('text()[1]=sql:column("B.leftID")') = 1

or even

select ...
from A
    inner join B on A.TypeId=B.LeftTypeId
        and A.relatedID.exist('/Id[text()[1]=sql:column("B.leftID")]') = 1

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