sql-servert-sql

Allocate quantities until total met


I want to write a T-SQL query that allocates ToAllocate numbers to the reference number by column ID1. Rank indicates the order of allocation and the last column shows the result I need.

Example:

ID1 ID2 Rank ToAllocate Reference Result
xxx a 1 100 350 100
xxx b 2 200 350 200
xxx c 3 100 350 50
yyy a 1 40 100 40
yyy b 2 70 100 60
yyy c 3 10 100 0

This is a problem of running sum, for each id1 we have a reference qty to allocate, and depending on rank we know to which id2 allocate the resources, so for xxx, we have 350 -100 (to id2 a) -200 (to id2 b) -100 (to id2 c). For the last id2, the reference qty is not enough so we have to use the available remainder.


Solution

  • Here is my solution as told before in the comments

    ;with
    d as (
        select *
        from ( values
            ('xxx', 'a', 1, 100, 350, 100),
            ('xxx', 'b', 2, 200, 350, 200),
            ('xxx', 'c', 3, 100, 350, 50),
            ('yyy', 'a', 1, 40, 100, 40),
            ('yyy', 'b', 2, 70, 100, 60),
            ('yyy', 'c', 3, 10, 100, 0)
        ) x (ID1, ID2, Rnk, ToAllocate, Reference, DesiredResult)
    ),
    n as (
        select *, SUM(ToAllocate) over (partition by id1 order by rnk) Need
        from d
    )
    select *, iif(Reference - need < 0, iif(abs(need-reference)>ToAllocate, 0, ToAllocate - (need-reference)), ToAllocate) CalculatedResult
    from n