SQL Server zapytanie rekurencyjne

0

Witam
Mam tabelę wygenerowaną przez EntityFramework, która zawiera pary liczb całkowitych (foreign key do tej samej tabeli tzn. rola do mechanizmu uprawnień).

Mam przykładowe dane:

parent child
2002 2003
2003 2006
2003 2004
2004 2005
2006 2007

W załączniku umieściłem obrazek, który to pokazuje w formie drzewa:
role_hier.png
Jak widać na obrazku dla argumentu 2002 chcę uzyskać listę id:
2004, 2005, 2003, 2006, 2007
Dla argumentu 2003 chcę uzyskać listę:
2004, 2006, 2005, 2007
Dla argumentu 2006 chcę uzyskać:
2007

Tabela wygląda w sposób następujący:
e107d9f0c7.png

Argument zapytania: id roli rodzica.

Rozumiem, że problem należy rozwiązać za pomocą rekurencji, czyli recursive CTE. Mniej więcej jest to opisane na tej stronie:
http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/

Wyskrobałem coś takiego, co jest źle:

WITH RoleHier AS
(
-- initialization
	SELECT
		dbo.ChildParentRole.ChildRoleId,
		dbo.ChildParentRole.ParentRoleId 
	FROM dbo.ChildParentRole
UNION ALL
-- recursive execution
	SELECT
		e.ChildRoleId, 
		e.ParentRoleId 
	FROM ChildParentRole e 
	INNER JOIN RoleHier h ON h.ChildRoleId = e.ParentRoleId
)

SELECT * FROM RoleHier WHERE ParentRoleId = 2002;

Przyznaję, że tego nie rozumiem i będę wdzięczny za wytłumaczenie jak to prawidłowo zapisać. Problem jest raczej z drugą częścią query: jaki jest warunek stopu rekurencji?

Pozdrawiam,

1

Dodaj sobie poziom rekurecji a zobaczysz, że problemem jest pierwsze zapytanie:

WITH RoleHier AS
(
-- initialization
    SELECT
        dbo.ChildParentRole.ChildRoleId,
        dbo.ChildParentRole.ParentRoleId,
        1 as RecLvl 
    FROM dbo.ChildParentRole
UNION ALL
-- recursive execution
    SELECT
        e.ChildRoleId,
        e.ParentRoleId,
        RecLvl+1
    FROM ChildParentRole e
    INNER JOIN RoleHier h ON h.ChildRoleId = e.ParentRoleId
)
SELECT * FROM RoleHier

Jak przeanalizujesz to na 1 poziomie masz wszystkie rekordy, dodaj do pierwszego zapytania to WHERE ParentRoleId = 2002
i zobacz co się stanie.

Reasumując pierwsze zapytanie to "anchor" (brak mi odpowiednika polskiego początek/kotwica) do którego "dobierasz rekordy".

1 użytkowników online, w tym zalogowanych: 0, gości: 1