递归CTE SQL返回所有后代和祖先

时间:2013-06-12 20:41:27

标签: sql sql-server-2008

鉴于此表......

CREATE TABLE [dbo].[Data](
    [Id] [int] NOT NULL,
    [Name] [varchar](50) NOT NULL,
    [ParentId] [int] NULL,
 CONSTRAINT [PK_Data] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

及相关数据......

BEGIN TRANSACTION;
INSERT INTO [dbo].[Data]([Id], [Name], [ParentId])
SELECT 1, N'George', 4 UNION ALL
SELECT 2, N'Amit', 1 UNION ALL
SELECT 3, N'Chad', 1 UNION ALL
SELECT 4, N'David', NULL UNION ALL
SELECT 5, N'Tess', 3 UNION ALL
SELECT 6, N'Emma', 3
COMMIT;
RAISERROR (N'[dbo].[Data]: Insert Batch: 1.....Done!', 10, 1) WITH NOWAIT;
GO

您能否为我提供2个单独的CTE SQL来返回给定ID的后代和祖先?

2 个答案:

答案 0 :(得分:1)

这样的事情会让你朝着正确的方向前进:

with childcte as (
  select id, name, parentid
  from data
  where id = 2
  union all
  select d.id, d.name, d.parentid
  from data d
    join childcte on d.parentid = childcte.id 
), parentcte as (
  select id, name, parentid
  from data
  where id = 2
  union all
  select d.id, d.name, d.parentid
  from data d
    join parentcte on d.id  = parentcte.parentid 
  )
select *
from childcte
union 
select *
from parentcte;

答案 1 :(得分:1)

试试这个CTE。您还需要与您的用户表联合。我得到了与您正在搜索的用户相关的所有层次结构,并且将获得所有孩子。

查询将从根开始,这就是查询的第一部分其中ParentId = null 的原因。第二个是让所有孩子的根,所以第四。

 declare @UserId int
 select @UserId = 1

WITH hierarchy (Id, ParentId) AS
(
      SELECT
            Id, ParentId
      FROM
            [dbo].[Data]
      WHERE 
            parentid IS NULL 
      UNION ALL 
      SELECT
            u1.Id, u1.ParentId 
      FROM
             [dbo].[Data] u1  
      INNER JOIN hierarchy ON 
            u1.ParentId = hierarchy.Id 
)

select * From hierarchy where ParentId = @UserId;