There is a residue of item # 1 for example 7pcs.
This product has 16 lines in the parish table. with different quantities and for example 6 lines in the table of expenses
As a result, knowing the final balance, I need to form a query to the parishes table starting with the last one and select only those lines that include this balance.
For example, recent parishes
line 13 - 2pcs
line 14 - 4pcs
line 15 - 2pcs
Should choose line 15 2pcs and the price to take the parish
line 14 4pcs and price
and line 13 1pcs and the price of the arrival ..
How to implement such a query in the database?

    1 answer 1

    Unfortunately, in the comments suggested that does not support the syntax given in the first part of the answer. Also note that perhaps the problem can be solved using stored procedures, or by changing the architectural approach. Well, or DBMS))


    For DBMS supporting the SQL-2008 standard

    To solve the problem, you need a query using the over(partition by... expression, which will allow you to receive a cumulative receipt amount by product. Please note (partition by ...) added sorting order by p.prihoddate desc descending the arrival date to allow accumulation Next, in the external query, we cut off where nsum - prihod < 7 the amounts that have exceeded our balance. Note that there is a subtraction in the condition, this is so that the partially spent income is included in the sample. Next, we need to calculate the stop. weave for coming, and here it is necessary to resort to the conditional statement case when nsum < 7 then prihod else prihod - (nsum - 7) end ostatok , I hope you will easily will pick up analogue in conditions essence that neraskhodovannyh parishes derive the remainder equal to parish. and for partially consumed we subtract the difference between the cumulative amount and the total balance of the product. Sorry, tested on

     select tovarid, case when nsum < 7 then prihod else prihod - (nsum - 7) end ostatok, prihodprice, prihoddate from (select p.*, sum(p.prihod) over (partition by p.tovarid order by p.prihoddate desc) nsum from prihods p where p.tovarid = 1) where nsum - prihod < 7 

    Initial data for the request

    Initial data for the request

    Gives out

    issue


    Solution for earlier SQL standards

    But after all, the cumulative sum can be taken differently - by adding another level of the subquery.

     select tovarid, case when psum + prihod < 7 then prihod else (7 - psum ) end ostatok, prihodprice, prihoddate from (select p.*, nvl((select sum(p2.prihod) from prihods p2 where p2.prihoddate > p.prihoddate and p2.tovarid = p.tovarid),0) psum from prihods p where p.tovarid = 1) where psum < 7 

    Note that the cumulative amount is now taken immediately without taking into account the arrival of the current line, so the selection condition of psum < 7 and the conditional case when psum + prihod < 7 then prihod else (7 - psum ) end ostatok . Now I see no obstacles to performing a query on . I do not dare judge how optimal he is. Note that the operator nvl(...,0) added to in the sum calculation expression in the case when the first parameter is null, it returns the second parameter, in other cases the first one. We need it to put the value 0 as a psum, when the innermost query does not return a single line. Analogue of nvl in is IFNULL

    PS That would seem to have bypassed the lack of window functions in , but the top query could be copied without problems into a sample of several products at once, and the bottom one is more complicated. Well, the optimality in the top will certainly win.

    • one
      Comments are not intended for extended discussion; conversation moved to chat . - Nofate