Advertisement
Guest User

Untitled

a guest
Jun 26th, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.80 KB | None | 0 0
  1. Buckets
  2. ----------------------------------------
  3. Bucket BucketAccount TotalAmount
  4. 1 GB111 30
  5. 2 GB111 50
  6. 3 GB222 100
  7. 4 GB333 150
  8.  
  9.  
  10. Holdings (before execution)
  11. ------------------------------------------------------------------------------
  12. ID Account Amount Bucket AmountApplied
  13. 1 GB111 50 null null
  14. 2 GB111 40 null null
  15. 3 GB222 30 null null
  16. 4 GB222 40 null null
  17. 5 GB333 -100 null null
  18. 6 GB333 250 null null
  19. 7 GB333 50 null null
  20.  
  21. If(OBJECT_ID('tempdb..#buckets') Is Not Null)
  22. Begin
  23. Drop Table #buckets
  24. End
  25.  
  26. CREATE TABLE #buckets
  27. (
  28. Bucket int,
  29. BucketAccount nvarchar(10),
  30. TotalAmount Decimal
  31. );
  32.  
  33. insert into #buckets values
  34. (1, 'GB111', 30),
  35. (2, 'GB111', 50),
  36. (3, 'GB222', 100),
  37. (4, 'GB333', 150)
  38.  
  39.  
  40.  
  41. If(OBJECT_ID('tempdb..#holdings') Is Not Null)
  42. Begin
  43. Drop Table #holdings
  44. End
  45.  
  46. CREATE TABLE #holdings
  47. (
  48. ID int,
  49. Account nvarchar(10),
  50. Amount decimal,
  51. Bucket int null,
  52. TotalAmount decimal null
  53. );
  54.  
  55. insert into #holdings (ID, Account, Amount, Bucket, TotalAmount)
  56. values
  57. (1, 'GB111', 50, null, null),
  58. (2, 'GB111', 40, null, null),
  59. (3, 'GB222', 30, null, null),
  60. (4, 'GB222', 40, null, null),
  61. (5, 'GB333', -100, null, null),
  62. (6, 'GB333', 250, null, null),
  63. (7, 'GB333', 50, null, null)
  64.  
  65.  
  66. select *
  67. from
  68. (select
  69. hold.Account, maxIds.ID as SubTotalId, sum(hold.Amount) as PartAmount
  70. from #holdings hold
  71. inner join #holdings maxIds
  72. on hold.Account = maxIds.Account
  73. and hold.Id <= maxIds.ID
  74. group by hold.Account, maxIds.Id) partHoldings
  75.  
  76. right join
  77. (select buckets.BucketAccount, subBuckets.Bucket, sum(buckets.TotalAmount) as PartAmount
  78. from #buckets buckets
  79. inner join #buckets subBuckets
  80. on buckets.BucketAccount = subBuckets.BucketAccount
  81. and buckets.Bucket <= subBuckets.Bucket
  82. group by buckets.BucketAccount, subBuckets.Bucket) partBuckets
  83.  
  84. on partHoldings.Account = partBuckets.BucketAccount
  85. and partHoldings.PartAmount >= partBuckets.PartAmount
  86.  
  87.  
  88. select
  89. -- * ,
  90. BucketAccount, Bucket, ID as holdingId,
  91. case
  92. when MinHoldingCoveringBucket < Id and Id < MaxHoldingCoveringBucket then Amount
  93. when MinHoldingCoveringBucket = Id and Id = MaxHoldingCoveringBucket then PartAmount - prevTotalPartAmount
  94. when MinHoldingCoveringBucket = Id and Id <> MaxHoldingCoveringBucket then holdPartAmount - prevTotalPartAmount
  95. when MinHoldingCoveringBucket <> Id and Id = MaxHoldingCoveringBucket then PartAmount - holdPrevPartAmount
  96. else null
  97. end as AmountApplied
  98. from
  99. (select
  100. holdingsBuckets.BucketAccount, holdingsBuckets.Bucket, holdingsBuckets.PartAmount, holdingsBuckets.prevTotalPartAmount
  101. , IsNull(MinHoldingCoveringBucket, minAccountHoldingId) as MinHoldingCoveringBucket
  102. , IsNull(MaxHoldingCoveringBucket, maxAccountHoldingId) as MaxHoldingCoveringBucket
  103.  
  104. , hold.ID, hold.Amount
  105. , partHoldings.PartAmount as holdPartAmount
  106. , partHoldings.prevPartAmount as holdPrevPartAmount
  107. from
  108. (select
  109. topLimits.*
  110. , min(botLimits.SubTotalId) as MinHoldingCoveringBucket
  111. from
  112. (select
  113. partBuckets.*
  114. , min(partHoldings.SubTotalId) as MaxHoldingCoveringBucket
  115. from
  116. (select subBuckets.BucketAccount, subBuckets.Bucket, sum(buckets.TotalAmount) as PartAmount, sum(buckets.TotalAmount) - subBuckets.TotalAmount as prevTotalPartAmount
  117. from #buckets buckets
  118. inner join #buckets subBuckets
  119. on buckets.BucketAccount = subBuckets.BucketAccount
  120. and buckets.Bucket <= subBuckets.Bucket
  121. group by subBuckets.BucketAccount, subBuckets.Bucket, subBuckets.TotalAmount) partBuckets
  122.  
  123. left join
  124. (select
  125. hold.Account, maxIds.ID as SubTotalId, sum(hold.Amount) as PartAmount
  126. from #holdings hold
  127. inner join #holdings maxIds
  128. on hold.Account = maxIds.Account
  129. and hold.Id <= maxIds.ID
  130. group by hold.Account, maxIds.Id) partHoldings
  131.  
  132. on partHoldings.Account = partBuckets.BucketAccount
  133. and partHoldings.PartAmount >= partBuckets.PartAmount
  134.  
  135.  
  136. left join
  137. (select
  138. hold.Account, maxIds.ID as SubTotalId, sum(hold.Amount) as PartAmount
  139. from #holdings hold
  140. inner join #holdings maxIds
  141. on hold.Account = maxIds.Account
  142. and hold.Id <= maxIds.ID
  143. group by hold.Account, maxIds.Id) partHoldings2
  144.  
  145. on partBuckets.BucketAccount = partHoldings2.Account
  146. and partHoldings.SubTotalId >= partHoldings2.SubTotalId
  147. and partHoldings2.PartAmount > partBuckets.prevTotalPartAmount
  148.  
  149. group by partBuckets.BucketAccount, partBuckets.Bucket, partBuckets.PartAmount, partBuckets.prevTotalPartAmount) topLimits
  150.  
  151. left join
  152. (select
  153. hold.Account, maxIds.ID as SubTotalId, sum(hold.Amount) as PartAmount
  154. from #holdings hold
  155. inner join #holdings maxIds
  156. on hold.Account = maxIds.Account
  157. and hold.Id <= maxIds.ID
  158. group by hold.Account, maxIds.Id) botLimits
  159.  
  160. on topLimits.BucketAccount = botLimits.Account
  161. and botLimits.PartAmount > topLimits.prevTotalPartAmount
  162. and botLimits.SubTotalId < topLimits.MaxHoldingCoveringBucket
  163.  
  164. group by topLimits.BucketAccount, topLimits.Bucket, topLimits.PartAmount, topLimits.prevTotalPartAmount, topLimits.MaxHoldingCoveringBucket) holdingsBuckets
  165.  
  166. inner join
  167. (select Account, min(Id) as minAccountHoldingId, max(id) as maxAccountHoldingId
  168. from #holdings
  169. group by Account) edgeAccountHoldings
  170.  
  171. on holdingsBuckets.BucketAccount = edgeAccountHoldings.Account
  172.  
  173. right join #holdings hold
  174. on holdingsBuckets.BucketAccount = hold.Account
  175. and IsNull(MinHoldingCoveringBucket, minAccountHoldingId) <= hold.ID
  176. and hold.ID <= IsNull(MaxHoldingCoveringBucket, maxAccountHoldingId)
  177.  
  178. left join
  179. (
  180. select
  181. hold.Account, maxIds.ID as SubTotalId, sum(hold.Amount) as PartAmount, sum(hold.Amount) - maxIds.Amount as prevPartAmount
  182. from #holdings hold
  183. inner join #holdings maxIds
  184. on hold.Account = maxIds.Account
  185. and hold.Id <= maxIds.ID
  186. group by hold.Account, maxIds.Id, maxIds.Amount
  187. ) partHoldings
  188.  
  189. on partHoldings.Account = holdingsBuckets.BucketAccount
  190. and hold.ID = partHoldings.SubTotalId) selectionData
  191.  
  192. Holdings
  193. --------------------------------------------------------------------------------------------------------------------------------------------
  194. ID Account Amount Bucket AmountApplied Comments
  195. 1 GB111 50 1 30 Applied 30. Bucket 1 is filled with 20 leftover, move to next bucket of same account
  196. 2 GB111 40 2 20 Insert new record. Applied 20 (from leftover in Bucket 1), and there is 30 leftover to cover in Bucket 2
  197. 3 GB222 30 2 30 Applied 30, 10 leftover in Bucket 2. We are out of holdings for this account, move on to next account
  198. 4 GB222 40 3 30 Applied 30, 70 leftover in Bucket 3
  199. 5 GB333 -100 3 **70** Applied 40, 30 leftover in bucket 3. Bucket is not filled and we are out of holdings for this account. Move on to next account
  200. 6 GB333 250 4 -100 Applied -100, 250 leftover in Bucket 4
  201. 7 GB333 50 4 250 Applied 250, Bucket 4 is filled with 0 leftover, move on to next account
  202. 8 GB333 50 null null Skip as Bucket 4 is already filled
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement