我再次与递归CTE挣扎。我有一个自引用表,每行都有一个得分。我需要通过分数对应父节点的排序顺序(也按分数排序)来解析叶节点的排序顺序。分组看起来像这样:
Groups Score
------------------------------------
Group 1 0.95
Group a 0.7
Group i 0.9
Group ii 0.7
Group b 0.9
Group iii 0.5
Group iv 1.0
Group 2 0.9
Group c 0.5
Group d 0.8
Group 3 1.0
这是预期的结果集:
GroupID GroupName Score Rank
------------------------------------
11 Group 3 1.0 1
7 Group iv 1.0 2
6 Group iii 0.5 3
3 Group i 0.9 4
4 Group ii 0.7 5
10 Group d 0.8 6
9 Group c 0.5 7
这是示例记录。提前谢谢。
declare @tblGroups table (
GroupID int,
GroupName nvarchar(50),
ParentID int,
Score float
)
insert into @tblGroups values (1, 'Group 1', null, 0.95)
insert into @tblGroups values (2, 'Group a', 1, 0.7)
insert into @tblGroups values (3, 'Group i', 2, 0.9)
insert into @tblGroups values (4, 'Group ii', 2, 0.7)
insert into @tblGroups values (5, 'Group b', 1, 0.9)
insert into @tblGroups values (6, 'Group iii', 5, 0.5)
insert into @tblGroups values (7, 'Group iv', 5, 1.0)
insert into @tblGroups values (8, 'Group 2', null, 0.9)
insert into @tblGroups values (9, 'Group c', 8, 0.5)
insert into @tblGroups values (10, 'Group d', 8, 0.8)
insert into @tblGroups values (11, 'Group 3', null, 1.0)
select
g.*
from
@tblGroups g
答案 0 :(得分:2)
像这样的东西应该工作。 RIGHT
是为了确定订单是否为6位数,否则它将重叠并弄乱下一个递归级别
WITH myCTE
AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Score desc) AS RowNumber,
RIGHT('000000' + CAST(ROW_NUMBER() OVER (ORDER BY Score desc) AS VARCHAR(MAX)),6) AS Overall
FROM tblGroups
WHERE ParentId IS NULL
UNION ALL
SELECT tblGroups.*, ROW_NUMBER() OVER (ORDER BY myCTE.RowNumber , tblGroups.Score desc) AS RowNumber,
Overall + RIGHT('000000' + CAST(ROW_NUMBER() OVER (ORDER BY myCTE.RowNumber , tblGroups.Score desc) AS VARCHAR(MAX)),6) AS Overall
FROM tblGroups
JOIN myCTE
ON myCTE.GroupID = tblGroups.ParentID
)
SELECT *
FROM myCTE
WHERE NOT EXISTS
(
SELECT 1
FROM tblGroups AS ParentTbl
WHERE myCTE.GroupID = ParentTbl.ParentID
)
ORDER BY overall;
答案 1 :(得分:2)
编辑:根据以下评论,问题似乎比我想象的要容易得多:
declare @tblGroups table ( GroupId int, GroupName nvarchar(50), ParentId int, Score float )
insert into @tblGroups values (1, 'Group 1', null, 0.95)
insert into @tblGroups values (2, 'Group a', 1, 0.7)
insert into @tblGroups values (3, 'Group i', 2, 0.9)
insert into @tblGroups values (4, 'Group ii', 2, 0.7)
insert into @tblGroups values (5, 'Group b', 1, 0.9)
insert into @tblGroups values (6, 'Group iii', 5, 0.5)
insert into @tblGroups values (7, 'Group iv', 5, 1.0)
insert into @tblGroups values (8, 'Group 2', null, 0.9)
insert into @tblGroups values (9, 'Group c', 8, 0.5)
insert into @tblGroups values (10, 'Group d', 8, 0.8)
insert into @tblGroups values (11, 'Group 3', null, 1.0)
select * from @tblGroups
; with Greg as (
-- The roots have no parents.
select GroupId, GroupName, ParentId, Score,
Cast( Right( '00000' + Cast( Row_Number() over ( order by Score desc ) as VarChar(6) ), 6 ) as VarChar(1024) ) as OverallRank
from @tblGroups
where ParentId is NULL
union all
-- Add the children one generation at a time.
select T.GroupId, T.GroupName, T.ParentId, T.Score,
Cast( G.OverallRank + Right( '00000' + Cast( Row_Number() over ( order by T.Score desc ) as VarChar(6) ), 6 ) as VarChar(1024) )
from Greg as G inner join
@tblGroups as T on T.ParentId = G.GroupId
)
select *
from Greg as G
where not exists ( select 42 from @tblGroups where ParentId = G.GroupId ) -- Leaf nodes only.
order by OverallRank