code_junkie

How do you sort a tree stored using the nested set model?

Nov 11th, 2011
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.97 KB | None | 0 0
  1. root
  2. finances
  3. budgeting
  4. fy08
  5. projects
  6. research
  7. fabrication
  8. release
  9. trash
  10.  
  11. root
  12. finances
  13. budgeting
  14. fy08
  15. projects
  16. fabrication
  17. release
  18. research
  19. trash
  20.  
  21. CREATE VIEW dbo.tree_view
  22.  
  23. AS
  24.  
  25. SELECT t2.NodeID,t2.lft,t2.rgt ,t2.Name, COUNT(t1.NodeID) AS level
  26. FROM dbo.tree t1,dbo.tree t2
  27. WHERE t2.lft BETWEEN t1.lft AND t1.rgt
  28. GROUP BY t2.NodeID,t2.lft,t2.rgt,t2.Name
  29.  
  30. GO
  31.  
  32. ----------------------------------------------
  33.  
  34. DECLARE @CurrentNodeID int
  35. DECLARE @CurrentActualOrder int
  36. DECLARE @CurrentRequiredOrder int
  37. DECLARE @DestinationNodeID int
  38. DECLARE @i0 int
  39. DECLARE @i1 int
  40. DECLARE @i2 int
  41. DECLARE @i3 int
  42.  
  43. DECLARE @t TABLE (TopLft int,NodeID int NOT NULL,lft int NOT NULL,rgt int NOT NULL,Name varchar(50),RequiredOrder int NOT NULL,ActualOrder int NOT NULL)
  44.  
  45.  
  46. INSERT INTO @t (toplft,NodeID,lft,rgt,Name,RequiredOrder,ActualOrder)
  47. SELECT tv2.lft,tv1.NodeID,tv1.lft,tv1.rgt,tv1.Name,ROW_NUMBER() OVER(PARTITION BY tv2.lft ORDER BY tv1.ColumnToSort),ROW_NUMBER() OVER(PARTITION BY tv2.lft ORDER BY tv1.lft ASC)
  48. FROM dbo.tree_view tv1
  49. LEFT OUTER JOIN dbo.tree_view tv2 ON tv1.lft > tv2.lft and tv1.lft < tv2.rgt and tv1.level = tv2.level+1
  50. WHERE tv2.rgt > tv2.lft+1
  51.  
  52. DELETE FROM @t where ActualOrder = RequiredOrder
  53.  
  54.  
  55. WHILE EXISTS(SELECT * FROM @t WHERE ActualOrder <> RequiredOrder)
  56. BEGIN
  57.  
  58.  
  59. SELECT Top 1 @CurrentNodeID = NodeID,@CurrentActualOrder = ActualOrder,@CurrentRequiredOrder = RequiredOrder
  60. FROM @t
  61. WHERE ActualOrder <> RequiredOrder
  62. ORDER BY toplft,requiredorder
  63.  
  64. SELECT @DestinationNodeID = NodeID
  65. FROM @t WHERE ActualOrder = @CurrentRequiredOrder AND TopLft = (SELECT TopLft FROM @t WHERE NodeID = @CurrentNodeID)
  66.  
  67. SELECT @i0 = CASE WHEN c.lft < d.lft THEN c.lft ELSE d.lft END,
  68. @i1 = CASE WHEN c.lft < d.lft THEN c.rgt ELSE d.rgt END,
  69. @i2 = CASE WHEN c.lft < d.lft THEN d.lft ELSE c.lft END,
  70. @i3 = CASE WHEN c.lft < d.lft THEN d.rgt ELSE c.rgt END
  71. FROM dbo.tree c
  72. CROSS JOIN dbo.tree d
  73. WHERE c.NodeID = @CurrentNodeID AND d.NodeID = @DestinationNodeID
  74.  
  75. UPDATE dbo.tree
  76. SET lft = CASE WHEN lft BETWEEN @i0 AND @i1 THEN @i3 + lft - @i1
  77. WHEN lft BETWEEN @i2 AND @i3 THEN @i0 + lft - @i2
  78. ELSE @i0 + @i3 + lft - @i1 - @i2
  79. END,
  80. rgt = CASE WHEN rgt BETWEEN @i0 AND @i1 THEN @i3 + rgt - @i1
  81. WHEN rgt BETWEEN @i2 AND @i3 THEN @i0 + rgt - @i2
  82. ELSE @i0 + @i3 + rgt - @i1 - @i2
  83. END
  84. WHERE lft BETWEEN @i0 AND @i3
  85. AND @i0 < @i1
  86. AND @i1 < @i2
  87. AND @i2 < @i3
  88.  
  89. UPDATE @t SET actualorder = @CurrentRequiredOrder where NodeID = @CurrentNodeID
  90. UPDATE @t SET actualorder = @CurrentActualOrder where NodeID = @DestinationNodeID
  91.  
  92. DELETE FROM @t where ActualOrder = RequiredOrder
  93.  
  94. END
  95.  
  96. A
  97. /
  98. B C
  99. /
  100. D E
  101.  
  102. 1 A 10
  103. 2 B 3
  104. 4 C 9
  105. 5 D 6
  106. 7 E 8
  107.  
  108. 1 A 10
  109. 2 B 3
  110. 4 C 9
  111. 7 D 8
  112. 5 E 6
Add Comment
Please, Sign In to add comment