代码之家  ›  专栏  ›  技术社区  ›  Ben Gribaudo

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

  •  0
  • Ben Gribaudo  · 技术社区  · 10 年前

    是否可以在两个T-SQL之间实现连接 nodes() 通过过滤第二个 节点() 基于第一个?

    在下面的示例中,我试图返回一个显示 PersonID , Name Position 。我试图引用 @id 第一个 节点() 的上下文节点 节点() XQuery语句不起作用。不返回职位名称。

    有什么想法吗?

    非常感谢。

    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 回复  |  直到 10 年前
        1
  •  3
  •   Jayvee    10 年前

    使用按值联接而不是按节点交叉应用应该有效;投影中的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)')
    
        2
  •  2
  •   Gouri Shankar Aechoor    10 年前

    这里和那里有些小改动,但与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')