Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

tsql - How to set the “Order” of Items in a hierarchy table in an easier and shorter way?

Refering to this post, here is the overall question and codes:

declare @tbl table (MenuItemID uniqueidentifier, PID uniqueidentifier, MenuID uniqueidentifier, SO tinyint, lvl tinyint)
;WITH 
cte (MenuItemID, PID, MenuID, SO, lvl) AS 
(
    select MenuItemID, PID, MenuID, SO, 0 from MenuItems
        where del = 0 and Perms = 1 and MenuID = @MenuID and MenuID = PID
    UNION ALL
    SELECT MenuItems.MenuItemID, MenuItems.PID, MenuItems.MenuID, MenuItems.SO, cte.lvl + 1 FROM MenuItems 
        JOIN cte ON cte.MenuItemID = MenuItems.PID
    ) 
    select * from cte
        ORDER BY lvl, SO
insert into @tbl select * from cte

declare @tbl2 table (MenuItemID uniqueidentifier, PID uniqueidentifier, MenuID uniqueidentifier, SO tinyint, lvl tinyint)
;with hier (MenuItemID, PID, MenuID, SO, lvl, FullSO) as
(select l0.*, convert(varchar(max),right('000'+convert(varchar(3),SO),3)) FullSO 
 from @tbl l0 where lvl=0
 union all
 select ln.*, lp.FullSO+','+right('000'+convert(varchar(3),ln.SO),3) FullSO
 from @tbl ln
 join hier lp on ln.PID = lp.MenuItemID)

insert into @tbl2 
 select MenuItemID, 
       PID, 
       MenuID,
       rank() over (partition by PID order by SO) SO,
       lvl
from hier
order by FullSO, SO

 update MenuItems set SO = h.SO
    from MenuItems as mi
    join @tbl2 h on mi.MenuItemID = h.MenuItemID and mi.MenuID = h.MenuID

I'd like to know whether there is an easier and shorter way for this code?

Thanks in advance,

Kardo

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You will still need a recursive CTE to determine which top-level records for the hierarchy have del = 0 and Perms = 1, but the following should be simpler:

WITH cte AS 
(select MenuItemID, PID, MenuID, SO, 
        rank() over (partition by PID order by SO) newSO
 from MenuItems
 where del = 0 and Perms = 1 and MenuID = @MenuID and MenuID = PID
 UNION ALL
 SELECT m.MenuItemID, m.PID, m.MenuID, m.SO, 
        rank() over (partition by m.PID order by m.SO) newSO
 FROM MenuItems m
 JOIN cte c ON c.MenuItemID = m.PID
) 
update MenuItems set SO = h.newSO
from MenuItems as mi
join cte h on mi.MenuItemID = h.MenuItemID and mi.MenuID = h.MenuID;

SQLFiddle here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...