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 № 1Poszukujesz 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