Pregunta

En el código siguiente, estoy usando un CTE (Expresión de tabla común) recursivo en SQL Server 2005 para intentar encontrar el nivel superior de una estructura jerárquica básica.La regla de esta jerarquía es que cada CustID tiene un ParentID y si el CustID no tiene padre, entonces ParentID = CustID y es el nivel más alto.

DECLARE @LookupID int

--Our test value
SET @LookupID = 1

WITH cteLevelOne (ParentID, CustID) AS
(
        SELECT   a.ParentID, a.CustID
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID
        WHERE c.CustID <> a.CustomerID
)

Entonces, si tblCustomer se ve así:

ParentID    CustID
5            5
1            8
5            4
4            1

El resultado que obtengo del código anterior es:

ParentID    CustID
4            1
5            4
5            5

Lo que quiero es sólo la última fila de ese resultado:

ParentID    CustID
5            5

¿Cómo devuelvo el último registro generado en el CTE (que sería el CustID de nivel más alto)?

También tenga en cuenta que hay varias jerarquías de CustID no relacionadas en esta tabla, por lo que no puedo simplemente hacer SELECT * FROM tblCustomer WHERE ParentID = CustID.No puedo realizar pedidos por ParentID o CustID porque el número de identificación no está relacionado con su ubicación en la jerarquía.

¿Fue útil?

Solución

Si solo desea obtener la profundidad de recursividad más alta, ¿no podría hacer algo como esto? Entonces, cuando realmente consulte el CTE, simplemente busque la fila con max (Profundidad).Al igual que:

DECLARE @LookupID int

--Our test value
SET @LookupID = 1;

WITH cteLevelOne (ParentID, CustID, Depth) AS
(
        SELECT   a.ParentID, a.CustID, 1
        FROM     tblCustomer AS a
        WHERE    a.CustID = @LookupID
    UNION ALL
        SELECT   a.ParentID, a.CustID, c.Depth + 1
        FROM     tblCustomer AS a
        INNER JOIN cteLevelOne AS c ON a.CustID = c.ParentID 
        WHERE c.CustID <> a.CustID
)
select * from CTELevelone where Depth = (select max(Depth) from CTELevelone)

o, adaptando lo que sugiere trevor, esto podría usarse con el mismo CTE:

select top 1 * from CTELevelone order by Depth desc

No creo que CustomerID fuera necesariamente lo que querías ordenar en el caso que describiste, pero tampoco tenía muy clara la pregunta.

Otros consejos

No estoy seguro de entender completamente el problema, pero para solucionarlo puedes intentar:

SELECT TOP 1 FROM cteLevelOne ORDER BY CustID DESC

Eso supone que el CustID también está en orden como en el ejemplo, y no algo así como un GUID.

Primero, el cte no finalizará si alguno de los padres e hijos es el mismo.Como es un CTE recursivo, debe finalizarse.Si el padre y el cliente son iguales, el ciclo no finalizará.

Msg 530, nivel 16, Estado 1, línea 15 La declaración terminó.La recursividad máxima 100 se agotó antes de completar la declaración.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top