Encontrar migas de pan para conjuntos anidados

Estoy usando conjuntos anidados (también conocido como recorrido de árbol de pedido anticipado modificado) para almacenar una lista de grupos, y estoy tratando de encontrar una forma rápida de generar migas de pan (como una cadena, no una tabla) para TODOS los grupos a la vez . Mis datos también se almacenan utilizando el modelo de lista de adyacencia (hay activadores para mantener los dos sincronizados).

Así por ejemplo

ID   Name    ParentId  Left   Right
0    Node A  0         1      12
1    Node B  0         2      5
2    Node C  1         3      4
3    Node D  0         6      11
4    Node E  3         7      8
5    Node F  4         9      9

Que representa el árbol:

Nodo ANodo BNodo CNodo DNodo ENodo F

Me gustaría poder tener una función definida por el usuario que devuelva una tabla:

ID  Breadcrumb
0   Node A
1   Node A > Node B
2   Node A > Node B > Node C
3   Node A > Node D
4   Node A > Node D > Node E
5   Node A > Node D > Node F

Para hacer esto un poco más complicado (aunque está fuera del alcance de la pregunta), también tengo restricciones de usuario que deben respetarse. Entonces, por ejemplo, si solo tengo acceso a id = 3, cuando ejecuto la consulta debería obtener:

ID  Breadcrumb
3   Node D
4   Node D > Node E
5   Node D > Node F

Tengo una función definida por el usuario que toma un ID de usuario como parámetro y devuelve una tabla con los ID de todos los grupos que son válidos, siempre y cuando en algún lugar de la consulta

WHERE group.id IN (SELECT id FROM dbo.getUserGroups(@userid))

funcionará

Tengo una función escalar existente que puede hacer esto, pero simplemente no funciona en un número razonable de grupos (toma> 10 segundos en 2000 grupos). Toma un groupid y userid como parámetro, y devuelve un nvarchar. Encuentra los grupos de padres dados (1 consulta para tomar los valores izquierdo / derecho, otra para encontrar los padres), restringe la lista a los grupos a los que el usuario tiene acceso (usando la misma cláusula WHERE que la anterior, por lo que otra consulta), y luego usa un cursor para pasar por cada grupo y agregarlo a una cadena, antes de finalmente devolver ese valor.

Necesito un método para hacerlo que se ejecute rápidamente (por ejemplo, <= 1s), sobre la marcha.

Esto está en SQL Server 2005.

Respuestas a la pregunta(6)

Su respuesta a la pregunta