在递归表

时间:2018-01-16 11:09:01

标签: sql-server

我有以下表格

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

我尝试创建一个查询,它将返回一对ID,ParentID列表。例如,我有关注数据

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

我希望在ID = 5时搜索以下列表:

ID  ParentID
5   3
3   1
1   0

如果我按ID = 15进行搜索,则会看到该序列已被识别,我将获得以下列表。

ID  ParentID
15  8

我使用临时表来使其工作,我的代码如下:

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

它有效,但我确信有更好的方法。我发现了一些奇怪的查询,这些查询很可能会做类似的事情,但我无法转换它以满足我的需求。

例如,我发现了以下问题,但我无法将其转换为与我的表一起使用。我发现的所有查询都有类似的答案。

1 个答案:

答案 0 :(得分:1)

您正在寻找递归查询。请参阅以下示例:

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

<强>输出:

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