Guest User

Untitled

a guest
Oct 28th, 2016
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.03 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=0, N=1 Затравочная запись выбрана первой частью
  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 Т.к. N=1 в качестве id был взят child, что дало новый корень (5)
  81. id=4, child=6, old_n=0, N=0
  82. id=6, child=6, old_n=1, N=1 тут все аналогично
  83. На следующем уровне рекурсии для записи 5 потомков нет, значит
  84. она уже ничего не породит. Следим за 6
  85. id=4, child=7, old_n=0, N=0 По условию (old_n=1 or N=0) взята только 1 запись из Nums N=0
  86. child взят из следующей дочерней записи
  87. id=6, child=7, old_n=1, N=0 т.к. old_n=1 то берется 2 записи Nums (0,1)
  88. у данной N=0, поэтому корень сохранился id=4
  89. id=7, child=7, old_n=1, N=1 N=1 поэтому корень 6 заменен на 7
  90. И аналогично следующий уровень рекурсии
  91. id=4, child=8, old_n=0, N=0
  92. id=6, child=8, old_n=0, N=0
  93. id=7, child=8, old_n=1, N=0
  94. id=8, child=8, old_n=1, N=1 Затравка для следующего уровня, если бы он был
  95.  
  96. create table tree
  97. (
  98. ID int not NULL primary key,
  99. ParentID int NULL foreign key references tree (ID)
  100. );
  101.  
  102. insert into tree (ID, ParentID) values
  103. (1, NULL),
  104. (2, 1), (3, 1),
  105. (4, NULL),
  106. (5, 4),
  107. (6, 4),
  108. (7, 6),
  109. (8, 7);
  110.  
  111. create index IX_tree_ParentID on tree (ParentID) include (ID);
  112.  
  113. create view treeView
  114. as
  115. with cte(ID, ParentID, Level)
  116. as
  117. (
  118. select t.ID, t.ParentID, 0
  119. from tree t
  120. where ParentID is NULL
  121. union all
  122. select t.ID, t.ParentID, cte.Level + 1
  123. from tree t
  124. join cte on cte.ID = t.ParentID
  125. )
  126. select ID, ParentID, Level
  127. from cte
  128. GO
  129.  
  130. create function treeItemDescendants2
  131. (
  132. @itemID int
  133. )
  134. returns table
  135. as return
  136. with cte(ID, ParentID, Level)
  137. as
  138. (
  139. select t.ID, t.ParentID, 1
  140. from tree t
  141. where ParentID = @itemID
  142. union all
  143. select t.ID, t.ParentID, cte.Level + 1
  144. from tree t
  145. join cte on cte.ID = t.ParentID
  146. )
  147. select ID, ParentID, Level
  148. from cte
  149. GO
  150.  
  151. select t.ID, d.ID as Child, t.Level, d.Level as ChildLevel
  152. from treeView t
  153. cross apply treeItemDescendants2(t.ID) d;
  154.  
  155. ID Child Level ChildLevel
  156. ----------- ----------- ----------- -----------
  157. 1 2 0 1
  158. 1 3 0 1
  159. 4 5 0 1
  160. 4 6 0 1
  161. 4 7 0 2
  162. 4 8 0 3
  163. 6 7 1 1
  164. 6 8 1 2
  165. 7 8 2 1
Add Comment
Please, Sign In to add comment