1

次のようなデータベース スキーマがあるとします。

RowId   ParentId   Name
------ ---------- ------
1       NULL      Level1
2       NULL      Level2
3       1         Leaf1
4       1         Leaf2
5       2         Leaf1
6       3         LeafX

基本的に、ツリーは次のようになります。

Level1
       Leaf1
             LeafX
       Leaf2
Level2
       Leaf1

最も効率的かつ動的な方法で、LeafX のすべての祖先 LEVEL を抽出する必要があります。

したがって、次のように出力されます: Leaf1、Leaf2、および Leaf1 (Level2 の)

T-SQLでこれを行うにはどうすればよいですか? ありがとう

4

4 に答える 4

3

これにより、必要な結果が得られます。

;with C as
(
  select T.rowid,
         T.parentid,
         T.name,
         1 as Lvl
  from YourTable as T
  where T.parentid is null
  union all
  select T.rowid,
         T.parentid,
         T.name,
         C.Lvl + 1
  from YourTable as T
    inner join C
       on T.parentid = C.rowid
)
select *
from C
where C.Lvl = (
               select C.lvl-1
               from C
               where C.name = 'LeafX'
              )

更新
そして、これはあなたにとってより速いかもしれません。データでテストする必要があります。

declare @Level int;

with C as
(
  select T.rowid,
         T.parentid
  from @t as T
  where T.name = 'LeafX'
  union all
  select T.rowid,
         T.parentid
  from @t as T
    inner join C
       on T.rowid = C.parentid
)
select @Level = count(*) - 1
from C;

with C as
(
  select T.rowid,
         T.parentid,
         T.name,
         1 as Lvl
  from @t as T
  where T.parentid is null
  union all
  select T.rowid,
         T.parentid,
         T.name,
         C.Lvl + 1
  from @t as T
    inner join C
       on T.parentid = C.rowid
  where C.Lvl < @Level
)
select *
from C
where C.Lvl = @Level;
于 2012-10-16T08:52:50.247 に答える
1

それにはいくつかの方法があります。私のお気に入りは、特別なテーブル Trees_Parents を作成することです。ここには、evere ノードのすべての親を格納します。だからそのような構造を持っているなら

RowId   ParentId   Name
------ ---------- ------
1       NULL      Level1
2       NULL      Level2
3       1         Leaf1
4       1         Leaf2
5       2         Leaf1
6       3         LeafX

Trees_Parents テーブルは次のようになります

RowId   ParentId
------ ----------
1       1     
2       2     
3       3
3       1        
4       4
4       1        
5       5
5       2        
6       6
6       1
6       3        

次に、すべての子を取得する必要がある場合は、次のように記述します

select RowID from Trees_Parents where ParentId = 1

ユニオンを避けるために、このテーブルに行selfを格納しています。必要ない場合は、次のように記述できます

select RowID from Trees_Parents where ParentId = 1 and ParentId <> RowId

そして、あなたが書くすべての親のために

select ParentId from Trees_Parents where RowId = 6 and ParentId <> RowId

Table_Name をテーブル Trees_Parents に格納して、さまざまなテーブルに使用することもできます

別の方法として、再帰的な WITH 句を書く方法もありますが、ツリーが大きくて頻繁に変更されない場合は、追加のテーブルに親データを格納する方がよいと思います

于 2012-10-16T07:41:45.793 に答える
1
declare @t table(rowid int, parentid int, name varchar(10))
insert @t values(1,NULL,'Level1')
insert @t values(2,NULL,'Level2')
insert @t values(3,1,'Leaf1')
insert @t values(4,1,'Leaf2')
insert @t values(5,2,'Leaf1')
insert @t values(6,3,'LeafX')

;with a as
(
select rowid, parentid, 0 level from @t where name = 'leafx'
union all
select t.rowid, t.parentid, level + 1 from @t t
join a on a.parentid = t.rowid
), b as
(
select rowid, parentid,name,  0 level from @t where parentid is null
union all
select t.rowid, t.parentid,t.name, level + 1 
from b join @t t on b.rowid = t.parentid
)
select rowid, parentid, name from b
where level = (select max(level)-1 from a)

rowid   parentid    name
5   2   Leaf1
3   1   Leaf1
4   1   Leaf2
于 2012-10-16T08:19:36.417 に答える
1

再帰的なソリューションを使用できます。Depth = Depth of your node - 1 ですべてのノードを取得する必要があります

declare @Temp table (RowId int, ParentId int, Name nvarchar(128))

insert into @Temp
select 1, null, 'Level1' union all
select 2, null, 'Level2' union all
select 3, 1, 'Leaf1' union all
select 4, 1, 'Leaf2' union all
select 5, 2, 'Leaf3' union all
select 6, 3, 'LeafX';

with Parents
as
(
    select T.RowId, 0 as Depth from @Temp as T where T.ParentId is null
    union all
    select T.RowId, P.Depth + 1
    from Parents as P
        inner join @Temp as T on T.ParentId = P.RowId
)
select T.Name
from Parents as P
    outer apply (select TT.Depth from Parents as TT where TT.RowId = 6) as CALC
    left outer join @Temp as T on T.RowId = P.RowId
where P.Depth = CALC.Depth - 1
于 2012-10-16T08:06:01.253 に答える