code_junkie

How to calculate the sum of values in a tree using SQL

Nov 10th, 2011
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. ID ParentID Points
  2. 1 0 230
  3. 2 1 150
  4. 3 0 80
  5. 4 1 110
  6. 5 4 54
  7. 6 4 342
  8.  
  9. Tree:
  10. 0
  11. |---
  12. 1 3
  13. |
  14. 2 4---
  15.  
  16. 5 6
  17.  
  18. ID Points Level1 Level2
  19. 1 230 150+110 150+110+54+342
  20. 2 150
  21. 3 80
  22. 4 110 54+342
  23. 5 54
  24. 6 342
  25.  
  26. SELECT rel.parent_id, SUM(tbl.points)
  27. FROM table tbl INNER JOIN relations rel ON tbl.id=rel.id
  28. WHERE rel.parent_id <> 0
  29. GROUP BY rel.parent_id;
  30.  
  31. WITH Parent (id, GrandParentId, parentId, Points, Level1Points, Level2Points)
  32. AS
  33. (
  34. -- Find root
  35. SELECT id,
  36. 0 AS GrandParentId,
  37. ParentId,
  38. Points,
  39. 0 AS Level1Points,
  40. 0 AS Level2Points
  41. FROM tblPoints ptr
  42. WHERE ptr.ParentId = 0
  43.  
  44. UNION ALL (
  45. -- Level2 Points
  46. SELECT pa.GrandParentId AS Id,
  47. NULL AS GrandParentId,
  48. NULL AS ParentId,
  49. 0 AS Points,
  50. 0 AS Level1Points,
  51. pa.Points AS Level2Points
  52. FROM tblPoints pt
  53. JOIN Parent pa ON pa.GrandParentId = pt.Id
  54. UNION ALL
  55. -- Level1 Points
  56. SELECT pt.ParentId AS Id,
  57. NULL AS GrandParentId,
  58. NULL AS ParentId,
  59. 0 AS Points,
  60. pt.Points AS Level1Points,
  61. 0 AS Level2Points
  62. FROM tblPoints pt
  63. JOIN Parent pa ON pa.Id = pt.ParentId AND pa.ParentId IS NOT NULL
  64. UNION ALL
  65. -- Points
  66. SELECT pt.id,
  67. pa.ParentId AS GrandParentId,
  68. pt.ParentId,
  69. pt.Points,
  70. 0 AS Level1Points,
  71. 0 AS Level2Points
  72. FROM tblPoints pt
  73. JOIN Parent pa ON pa.Id = pt.ParentId AND pa.ParentId IS NOT NULL )
  74. )
  75. SELECT id,
  76. SUM(Points) AS Points,
  77. SUM(Level1Points) AS Level1Points,
  78. CASE WHEN SUM(Level2Points) > 0 THEN SUM(Level1Points) + SUM(Level2Points) ELSE 0 END AS Level2Points
  79. FROM Parent
  80. GROUP BY id
  81. ORDER by id
  82.  
  83. CREATE FUNCTION CALC
  84. (
  85. @node integer,
  86. )
  87. returns
  88. (
  89. @total integer
  90. )
  91. as
  92. begin
  93. select @total = (select node_value from yourtable where node_id = @node);
  94.  
  95. declare @children table (value integer);
  96. insert into @children
  97. select calc(node_id) from yourtable where parent_id = @node;
  98.  
  99. @current = @current + select sum(value) from @children;
  100. return
  101. end
  102.  
  103. Id ParentId
  104. 1 NULL
  105. 11 1
  106. 12 1
  107. 110 11
  108. 111 11
  109. 112 11
  110. 120 12
  111. 121 12
  112. 122 12
  113. 123 12
  114. 124 12
  115.  
  116. Id Val
  117. 110 500
  118. 111 50
  119. 112 5
  120. 120 3000
  121. 121 30000
  122. 122 300000
  123.  
  124. ;WITH Data (Id, Val) AS
  125. (
  126. select t.Id, SUM(v.val) as Val from dbo.TestTable t
  127. join dbo.Amount v on t.Id = v.Id
  128. group by t.Id
  129. )
  130.  
  131. select cd.Id, ISNULL(SUM(cd.Val), 0) as Amount FROM
  132. (
  133. -- level 3
  134. select t.Id, d.val from TestTable t
  135. left join Data d on d.id = t.Id
  136.  
  137. UNION
  138.  
  139. -- level 2
  140. select t.parentId as Id, sum(y.Val) from TestTable t
  141. left join Data y on y.id = t.Id
  142. where t.parentId is not null
  143. group by t.parentId
  144.  
  145. UNION
  146.  
  147. -- level 1
  148. select t.parentId as Id, sum(y.Val) from TestTable t
  149. join TestTable c on c.parentId = t.Id
  150. left join Data y on y.id = c.Id
  151. where t.parentId is not null
  152. group by t.parentId
  153. ) AS cd
  154. group by id
  155.  
  156. Id Amount
  157. 1 333555
  158. 11 555
  159. 12 333000
  160. 110 500
  161. 111 50
  162. 112 5
  163. 120 3000
  164. 121 30000
  165. 122 300000
  166. 123 0
  167. 124 0
Add Comment
Please, Sign In to add comment