Advertisement
Guest User

Untitled

a guest
Oct 28th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. WITH
  2. Tree(Id,Parent,Level) AS (
  3. SELECT
  4. Node_Id
  5. ,0
  6. ,0
  7. FROM CatalogOKPD WHERE Node_Parent_Id = 0
  8. UNION ALL
  9. SELECT
  10. okpd.Node_Id
  11. ,okpd.Node_Parent_Id
  12. ,t.Level+1
  13. FROM CatalogOKPD okpd
  14. JOIN Tree t ON t.Id = okpd.Node_Parent_Id)
  15. ,FullTree(Id,Child,Level,ChildLevel) AS (
  16. SELECT
  17. t1.Id
  18. ,t2.Id
  19. ,t1.Level
  20. ,t2.Level
  21. FROM Tree t1
  22. JOIN Tree t2 ON t1.Id=t2.Parent
  23. UNION ALL
  24. SELECT
  25. ft.Id
  26. ,t.Id
  27. ,ft.Level
  28. ,t.Level
  29. FROM Tree t
  30. JOIN FullTree ft ON t.Parent = ft.Child
  31. )
  32. SELECT * FROM FullTree
  33.  
  34. id parent
  35. --- -------
  36. 1 0
  37. 2 1
  38. 3 1
  39. 4 0
  40. 5 4
  41. 6 4
  42. 7 6
  43. 8 7
  44.  
  45. id child level childlevel
  46. ----------- ----------- ----------- -----------
  47. 1 2 0 1
  48. 1 3 0 1
  49. 4 5 0 1
  50. 4 6 0 1
  51. 4 7 0 2
  52. 4 8 0 3
  53. 6 7 1 2
  54. 6 8 1 3
  55. 7 8 2 3
  56.  
  57. WITH
  58. Nums(N) AS (select 0 union select 1),
  59. Tree(id,Child,Level,ChildLevel,old_n) AS (
  60. SELECT Node_Id, Node_Id, 0, 0, 1
  61. FROM CatalogOKPD WHERE Node_Parent_Id = 0
  62. UNION ALL
  63. SELECT case when N=0 then t.id else okpd.Node_Id end,
  64. okpd.Node_Id, t.Level+N,
  65. t.ChildLevel+1, N
  66. FROM Tree t, CatalogOKPD okpd, Nums N
  67. WHERE t.Child = okpd.Node_Parent_Id and (old_n=1 or N=0)
  68. )
  69. select id, Child, Level, ChildLevel
  70. from Tree
  71. where old_n=0
  72. order by Level, id, ChildLevel
  73.  
  74. id=4, child=4, old_n=1, N=0 Затравочная запись выбрана первой частью
  75. она поступает на вход рекурсивной части как Tree ...
  76. Тут по parent=child к ней приклеены 2 записи (5, 6)
  77. old_n на входе равен 1 - значит по условию (old_n=1 or N=0)
  78. для каждой из них будут взяты 2 записи Nums, что даст 4 записи:
  79. id=4, child=5, old_n=0, N=0 В old_n перешел номер 0 из Nums
  80. id=5, child=5, old_n=1, N=1 Т.к. Nums.N=1 то и old_n=1 а в качестве id
  81. был взят child, что дало новый корень (5)
  82. id=4, child=6, old_n=0, N=0
  83. id=6, child=6, old_n=1, N=1 тут все аналогично
  84. На следующем уровне рекурсии для записи 5 потомков нет, значит
  85. она уже ничего не породит. Следим за 6
  86. id=4, child=7, old_n=0, N=0 По условию (old_n=1 or N=0) взята только 1 запись из Nums N=0
  87. child взят из следующей дочерней записи
  88. id=6, child=7, old_n=1, N=0 т.к. old_n=1 то берется 2 записи Nums (0,1)
  89. у данной N=0, поэтому корень сохранился id=4
  90. id=7, child=7, old_n=1, N=1 N=1 поэтому корень 6 заменен на 7
  91. И аналогично следующий уровень рекурсии
  92. id=4, child=8, old_n=0, N=0
  93. id=6, child=8, old_n=0, N=0
  94. id=7, child=8, old_n=1, N=0
  95. id=8, child=8, old_n=1, N=1 Затравка для следующего уровня, если бы он был
  96.  
  97. create table tree
  98. (
  99. ID int not NULL primary key,
  100. ParentID int NULL foreign key references tree (ID)
  101. );
  102.  
  103. insert into tree (ID, ParentID) values
  104. (1, NULL),
  105. (2, 1), (3, 1),
  106. (4, NULL),
  107. (5, 4),
  108. (6, 4),
  109. (7, 6),
  110. (8, 7);
  111.  
  112. create index IX_tree_ParentID on tree (ParentID) include (ID);
  113.  
  114. create view treeView
  115. as
  116. with cte(ID, ParentID, Level)
  117. as
  118. (
  119. select t.ID, t.ParentID, 0
  120. from tree t
  121. where ParentID is NULL
  122. union all
  123. select t.ID, t.ParentID, cte.Level + 1
  124. from tree t
  125. join cte on cte.ID = t.ParentID
  126. )
  127. select ID, ParentID, Level
  128. from cte
  129. GO
  130.  
  131. create function treeItemDescendants2
  132. (
  133. @itemID int
  134. )
  135. returns table
  136. as return
  137. with cte(ID, ParentID, Level)
  138. as
  139. (
  140. select t.ID, t.ParentID, 1
  141. from tree t
  142. where ParentID = @itemID
  143. union all
  144. select t.ID, t.ParentID, cte.Level + 1
  145. from tree t
  146. join cte on cte.ID = t.ParentID
  147. )
  148. select ID, ParentID, Level
  149. from cte
  150. GO
  151.  
  152. select t.ID, d.ID as Child, t.Level, d.Level as ChildLevel
  153. from treeView t
  154. cross apply treeItemDescendants2(t.ID) d;
  155.  
  156. ID Child Level ChildLevel
  157. ----------- ----------- ----------- -----------
  158. 1 2 0 1
  159. 1 3 0 1
  160. 4 5 0 1
  161. 4 6 0 1
  162. 4 7 0 2
  163. 4 8 0 3
  164. 6 7 1 1
  165. 6 8 1 2
  166. 7 8 2 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement