/ / Znajdź pary w rekursywnej tabeli [duplicate] - sql-server

Znajdź pary w rekursywnej tabeli [duplicate] - sql-server

Mam tabelę obserwatorów

CREATE TABLE [dbo].[MyTable2](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NOT NULL,
)

Próbuję utworzyć zapytanie, które zwróci listę identyfikatorów par, ParentID. Na przykład mam dane obserwatora

ID  ParentID
1   0
2   0
3   1
4   3
5   3
15  8

Chcę, gdy szukam według ID = 5, aby mieć następującą listę:

ID  ParentID
5   3
3   1
1   0

Jeśli szukam przez ID = 15, powinien zobaczyć, że sekwencja jest boken i otrzymam listę followign.

ID  ParentID
15  8

Użyłem tabeli tymczasowej, aby jej działanie działało, a mój kod jest następujący:

if object_id("tempdb..#Pairs") is not null
DROP TABLE #Pairs
create table #Pairs
(
ID INT,
ParentID INT
)
Declare @ID integer = 5;
Declare @ParentID integer;
while (@ID > 0)
BEGIN
SET @ParentID = null;             -- I set it to null so that I will be able to check in case the sequence is broken
select @ID=ID, @ParentID=ParentID
from MyTable
where ID = @ID;

if @ParentID IS NOT null
begin
Insert into #Pairs (ID, ParentID) Values (@ID, @ParentID)
SET @ID = @ParentID;
end
else
SET @ID = 0;
END
SELECT * from #Pairs

Działa, ale jestem pewien, że jest lepszy sposób na zrobienie tego. Znalazłem kilka dziwnych pytań, które były podejrzane o coś podobnego, ale nie byłem w stanie go przekonwertować, aby pokryć moje potrzeby.

Na przykład znalazłem następujące pytanie, ale nie byłem w stanie przekonwertować go do pracy z moją tabelą. Wszystkie zapytania, które znalazłem, miały podobne odpowiedzi.

Odpowiedzi:

1 dla odpowiedzi № 1

Poszukujesz zapytań rekurencyjnych. Zobacz następujący przykład:

SELECT * INTO tab FROM (VALUES
(1, 0),
(2, 0),
(3, 1),
(4, 3),
(5, 3),
(15, 8)) T(ID, ParentID);

DECLARE @whatAreYouLookingFor int = 5;

WITH Rec AS
(
SELECT * FROM tab WHERE ID=@whatAreYouLookingFor
UNION ALL
SELECT T.* FROM tab T JOIN Rec R ON R.ParentID=T.ID
)
SELECT * FROM Rec;

DROP TABLE tab

Wydajność:

ID  ParentID
--  --------
5   3
3   1
1   0