在T-SQL节点中引用当前上下文()XQuery

时间:2014-08-01 19:53:37

标签: xml tsql xquery-sql

是否可以通过根据第一个上下文节点过滤第二个nodes()来实现两个T-SQL nodes()调用之间的连接?

在下面的示例中,我尝试返回显示PersonIDNamePosition的表格。我尝试在第二个@id XQuery语句中引用第一个nodes()上下文节点的nodes()并不起作用。没有返回位置名称。

有什么想法吗?

谢谢!

DECLARE @xml xml  = '<Root>
    <People>
        <Person id="1">Frank</Person>
        <Person id="2">Joe</Person>
    </People>
    <Positions>
        <Position assignedToPerson="1">Engineer</Position>
        <Position assignedToPerson="2">Manager</Position>
    </Positions>
</Root>'

SELECT 
   PersonID = person.value('@id', 'NVARCHAR(50)'),
   Name = person.value('.', 'NVARCHAR(50)'),
   positionTitle = position.value('Position[1]', 'NVARCHAR(50)')
FROM 
   @xml.nodes('/Root/People/Person') People(person)
OUTER APPLY 
   @xml.nodes('/Root/Positions/Position[@assignedToPerson=.[@id]]') Positions(position)

2 个答案:

答案 0 :(得分:3)

使用按值连接而不是按节点交叉应用应该有效;然后投影中的positiontitle成为元素值(。):

DECLARE @xml xml  = '<Root>
    <People>
        <Person id="1">Frank</Person>
        <Person id="2">Joe</Person>
    </People>
    <Positions>
        <Position assignedToPerson="1">Engineer</Position>
        <Position assignedToPerson="2">Manager</Position>
    </Positions>
</Root>'

SELECT 
   PersonID = person.value('@id', 'NVARCHAR(50)'),
   Name = person.value('.', 'NVARCHAR(50)'),
   positionTitle = position.value('.', 'NVARCHAR(50)')
FROM 
   @xml.nodes('/Root/People/Person') People(person)
JOIN 
   @xml.nodes('/Root/Positions/Position') Positions(position)
ON person.value('@id', 'NVARCHAR(50)')= 
position.value('@assignedToPerson[1]','NVARCHAR(50)')

答案 1 :(得分:2)

这里和那里有一些细微的变化,但与Jayvee写的几乎相同。我已应用LEFT JOIN以确保符合OUTER APPLY逻辑

DECLARE @xml xml  = '<Root>
    <People>
        <Person id="1">Frank</Person>
        <Person id="2">Joe</Person>
        <Person id="3">Joe No Manager</Person>
    </People>
    <Positions>
        <Position assignedToPerson="1">Engineer</Position>
        <Position assignedToPerson="2">Manager</Position>
    </Positions>
</Root>'

SELECT   person.value('@id', 'INT') AS PersonID,
         person.value('.', 'NVARCHAR(50)') AS NAME,
         position.value('.', 'NVARCHAR(50)') AS positionTitle
FROM     @xml.nodes('/Root/People/Person') People(person)
LEFT JOIN    @xml.nodes('/Root/Positions/Position') Positions(position)
    ON   person.value('@id', 'INT') = position.value('@assignedToPerson', 'INT')