Puede emular la position()
función contando el número de nodos hermanos que preceden a cada nodo:
SELECT
code = value.value('@code', 'int'),
parent_code = value.value('../@code', 'int'),
ord = value.value('for $i in . return count(../*[. << $i]) + 1', 'int')
FROM @Xml.nodes('//value') AS T(value)
Aquí está el conjunto de resultados:
code parent_code ord
---- ----------- ---
1 NULL 1
11 1 1
111 11 1
12 1 2
121 12 1
1211 121 1
1212 121 2
Cómo funciona:
- El
for $i in .
cláusula define una variable llamada$i
que contiene el nodo actual (.
). Esto es básicamente un truco para solucionar la falta de XQuery de uncurrent()
similar a XSLT función. - El
../*
expresión selecciona todos los hermanos (hijos del padre) del nodo actual. - El
[. << $i]
predicado filtra la lista de hermanos a los que preceden (<<
) el nodo actual ($i
). - Nosotros
count()
el número de hermanos anteriores y luego suma 1 para obtener la posición. De esa forma, al primer nodo (que no tiene hermanos anteriores) se le asigna una posición de 1.