2012-07-22 11 views
12

Biorąc pod uwagę identyfikator podrzędny, muszę zwrócić kwerendę zawierającą wszystkich rodziców tego dziecka, a także ich rodziców, aż dotrę do rodzica root. Na przykład, biorąc pod uwagę dane:Rekurencyjnie znaleźć wszystkich przodków danego dziecka

ID/Parent ID 
1/0 
2/1 
3/2 
4/0 
5/3 

Więc gdybym przeszedł w ID 5 Chciałbym dostać zapytanie z rezultatów:

ID/Parent ID 
1/0 
2/1 
3/2 

Tabela ta nie działa z typem hierarchyid tak Podejrzewam, że trzeba będzie to zrobić przy użyciu CTE, ale nie mam pojęcia, jak to zrobić. Jeśli można to zrobić w zapytaniu SQL/proc, każda pomoc byłaby doceniana.

Dzięki

Odpowiedz

20

To jest mniej więcej to, co chcesz:

-- CTE to prepare hierarchical result set 
;WITH #results AS 
(
    SELECT id, 
      parentid 
    FROM [table] 
    WHERE id = @childId 
    UNION ALL 
    SELECT t.id, 
      t.parentid 
    FROM [table] t 
      INNER JOIN #results r ON r.parentid = t.id 
) 
SELECT * 
FROM #results; 

referencyjny:

przykład robocza:

-- create table with self lookup (parent id) 
CREATE TABLE #tmp (id INT, parentid INT); 

-- insert some test data 
INSERT INTO #tmp (id, parentid) 
SELECT 1,0 UNION ALL SELECT 2,1 UNION ALL SELECT 3,2 
UNION ALL SELECT 4,0 UNION ALL SELECT 5,3; 

-- prepare the child item to look up 
DECLARE @childId INT; 
SET @childId = 5; 

-- build the CTE 
WITH #results AS 
(
    SELECT id, 
      parentid 
    FROM #tmp 
    WHERE id = @childId 
    UNION ALL 
    SELECT t.id, 
      t.parentid 
    FROM #tmp t 
      INNER JOIN #results r ON r.parentid = t.id 
) 

-- output the results 
SELECT * 
FROM #results 
WHERE id != @childId 
ORDER BY id; 

-- cleanup 
DROP TABLE #tmp; 

wyjściowa:

1 | 0
2 | 1
3 | 2

+0

To jest po prostu niesamowite. Jedyne usprawnienie, jakie zrobiłem, to użycie klauzuli DISTINCT na ostatnim SELECT. Nie martwię się o wydajność z powodu małych zestawów nagrań, z którymi będę pracował. To odfiltrowuje duplikaty i po prostu zwraca hierarchie, które chcę, w oparciu o kryteria, które umieściłem w klauzuli WHERE pierwszego zapytania CTE (nie używając id = @childId w moim przypadku) – bcr

Powiązane problemy