我有以下分层表:
Table Category:
CategoryId, ParentCategoryId, CategoryName
1, null, SomeRoot
2, 1, SomeChild
3, 2, SomeGrandchild
4, 3, SomeGreatGrandchild
(请注意,此示例数据不包含比级别4更早的节点上的叶子,但这是可能的)。如果相关,数据将永远不会超过第4级。我想将它转换/转换为这个固定的4级显示器
CatId, Name1, Name2, Name3, Name4
1, SomeRoot, null, null, null
2, SomeRoot, SomeChild, null, null
3, SomeRoot, SomeChild, SomeGrandchild, null
4, SomeRoot, SomeChild, SomeGrandchild, SomeGreatGrandchild
我已经做了4次左外连接到类别表,并构建了一个巨大的case语句来检测用于ID字段的级别,但是不包括空行....任何想法?帮助!
答案 0 :(得分:3)
这可能不是最有效的查询,但它是最容易编码的:
declare @YourTable table (CategoryId int primary key, ParentCategoryId int , CategoryName varchar(50))
INSERT INTO @YourTable VALUES (1, null, 'SomeRoot')
INSERT INTO @YourTable VALUES (2, 1, 'SomeChild')
INSERT INTO @YourTable VALUES (3, 2, 'SomeGrandchild')
INSERT INTO @YourTable VALUES (4, 3, 'SomeGreatGrandchild')
INSERT INTO @YourTable VALUES (10, null, 'X_SomeRoot')
INSERT INTO @YourTable VALUES (20, 10, 'X_SomeChild')
INSERT INTO @YourTable VALUES (30, 20, 'X_SomeGrandchild')
Select
c1.CategoryId, c1.CategoryName, c2.CategoryName, c3.CategoryName, c4.CategoryName
From @YourTable c1
INNER JOIN @YourTable c2 On c1.CategoryId = c2.ParentCategoryId
INNER JOIN @YourTable c3 On c2.CategoryId = c3.ParentCategoryId
INNER JOIN @YourTable c4 On c3.CategoryId = c4.ParentCategoryId
WHERE c1.ParentCategoryId IS NULL
UNION
Select
c1.CategoryId, c1.CategoryName, c2.CategoryName, c3.CategoryName, NULL
From @YourTable c1
INNER JOIN @YourTable c2 On c1.CategoryId = c2.ParentCategoryId
INNER JOIN @YourTable c3 On c2.CategoryId = c3.ParentCategoryId
WHERE c1.ParentCategoryId IS NULL
UNION
Select
c1.CategoryId, c1.CategoryName, c2.CategoryName, NULL, NULL
From @YourTable c1
INNER JOIN @YourTable c2 On c1.CategoryId = c2.ParentCategoryId
WHERE c1.ParentCategoryId IS NULL
UNION
Select
c1.CategoryId, c1.CategoryName, NULL, NULL, NULL
From @YourTable c1
WHERE c1.ParentCategoryId IS NULL
ORDER BY 2,3,4,5
输出:
SortB CategoryId CategoryName CategoryName CategoryName CategoryName
----- ----------- ------------ ------------- ----------------- --------------------
1 1 SomeRoot NULL NULL NULL
2 1 SomeRoot SomeChild NULL NULL
3 1 SomeRoot SomeChild SomeGrandchild NULL
4 1 SomeRoot SomeChild SomeGrandchild SomeGreatGrandchild
1 10 X_SomeRoot NULL NULL NULL
2 10 X_SomeRoot X_SomeChild NULL NULL
3 10 X_SomeRoot X_SomeChild X_SomeGrandchild NULL
(7 row(s) affected)
答案 1 :(得分:0)
试试这个:
Select C.CatId, C.Name, PC.Name, GP.Name, GGP.Name
From Category C
Left Join Category PC On PC.CatId = C.ParentCategoryId
Left Join Category GP On GP .CatId = PC.ParentCategoryId
Left Join Category GGP On GGP .CatId = GP.ParentCategoryId
根据您的评论,如果您按如下方式编写UDF:
Create Function CatParentNames
( @CatId Integer )
Returns varchar(1000)
AS
Begin
Declare @outVal VarChar(1000)
Declare @ParId Integer
Select @ParId = ParentCategoryId, @outVal = Name
From Category
Where CatId = @CatId
While Exists(Select * From Category
Where CatId = @ParId)
Begin
Select @ParId = ParentCategoryId,
@outVal = Name + ', ' + @outVal
From Category
Where CatId = @ParId
End
Return @outVal
End
然后,按如下方式编写你的sql:
Select CatId, dbo.CatParentNames(CatId)
From Category
Where ParentCategoryId Is Not Null
答案 2 :(得分:0)
试试这个:
select a.CategoryId as CatId,
a.CategoryName as Name1,
cast(null as varchar(20)) as Name2,
cast(null as varchar(20)) as Name3,
cast(null as varchar(20)) as Name4
from @YourTable a
where a.ParentCategoryId is null
union all
select b.CategoryId,
a.CategoryName,
b.CategoryName,
null,
null
from @YourTable a
inner join @YourTable b
on a.CategoryId = b.ParentCategoryId
where a.ParentCategoryId is null
union all
select c.CategoryId,
a.CategoryName,
b.CategoryName,
c.CategoryName,
null
from @YourTable a
inner join @YourTable b
on a.CategoryId = b.ParentCategoryId
inner join @YourTable c
on b.CategoryId = c.ParentCategoryId
where a.ParentCategoryId is null
union all
select d.CategoryId,
a.CategoryName,
b.CategoryName,
c.CategoryName,
d.CategoryName
from @YourTable a
inner join @YourTable b
on a.CategoryId = b.ParentCategoryId
inner join @YourTable c
on b.CategoryId = c.ParentCategoryId
inner join @YourTable d
on c.CategoryId = d.ParentCategoryId
order by 2, 3, 4, 5
但是,如果您要将其与多列TreeView一起使用,那么这不是构建它的方法,如下所示:
(来源:digitaltools.com)
可以找到更多here.