Cumulative subtraction across rows









up vote
0
down vote

favorite












Table 1:
table1:



Table 2:
enter image description here



How can I subtract the Committed value (7) from the IncomingQuantity cumulatively across rows? So that the result would look like:
enter image description here



Thanks!










share|improve this question

















  • 2




    what is the version of SQL Server you are using ?
    – Squirrel
    Nov 9 at 0:15










  • Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
    – MrB
    Nov 9 at 18:03














up vote
0
down vote

favorite












Table 1:
table1:



Table 2:
enter image description here



How can I subtract the Committed value (7) from the IncomingQuantity cumulatively across rows? So that the result would look like:
enter image description here



Thanks!










share|improve this question

















  • 2




    what is the version of SQL Server you are using ?
    – Squirrel
    Nov 9 at 0:15










  • Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
    – MrB
    Nov 9 at 18:03












up vote
0
down vote

favorite









up vote
0
down vote

favorite











Table 1:
table1:



Table 2:
enter image description here



How can I subtract the Committed value (7) from the IncomingQuantity cumulatively across rows? So that the result would look like:
enter image description here



Thanks!










share|improve this question













Table 1:
table1:



Table 2:
enter image description here



How can I subtract the Committed value (7) from the IncomingQuantity cumulatively across rows? So that the result would look like:
enter image description here



Thanks!







sql sql-server tsql






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 8 at 22:52









MrB

365




365







  • 2




    what is the version of SQL Server you are using ?
    – Squirrel
    Nov 9 at 0:15










  • Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
    – MrB
    Nov 9 at 18:03












  • 2




    what is the version of SQL Server you are using ?
    – Squirrel
    Nov 9 at 0:15










  • Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
    – MrB
    Nov 9 at 18:03







2




2




what is the version of SQL Server you are using ?
– Squirrel
Nov 9 at 0:15




what is the version of SQL Server you are using ?
– Squirrel
Nov 9 at 0:15












Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
– MrB
Nov 9 at 18:03




Microsoft SQL Server 2016 (SP2-CU2-GDR) (KB4458621) - 13.0.5201.2 (X64) Aug 18 2018 07:38:15 Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)
– MrB
Nov 9 at 18:03












3 Answers
3






active

oldest

votes

















up vote
2
down vote













You need a cumulative sum and some arithmetic:



select t.*,
(case when running_iq - incomingquantity >= committed then 0
when running_iq > committed then running_iq - committed
else incomingquantity
end) as from_this_row
from (select t2.*, t1.committed,
sum(incomingquantity) over (order by rowid) as running_iq
from table1 t1 cross join
table2 t2
) t;





share|improve this answer






















  • Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
    – MrB
    Nov 8 at 23:39











  • @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
    – Gordon Linoff
    Nov 9 at 0:23

















up vote
1
down vote













you can also make use of the built-in functions such as ROW_NUMBER(), LAST_VALUE(), and LAG() with CASE



here is an example :



DECLARE 
@t1 TABLE ( ProductID VARCHAR(50), ICommitted INT)

INSERT INTO @t1 VALUES ('Some product', 7)

DECLARE
@t2 TABLE (RowID INT, DueDate DATE, IncommingQuantity INT)

INSERT INTO @t2 VALUES
(1,'2018-11-19', 5),
(2,'2018-11-20', 4),
(3,'2018-11-20', 4),
(4,'2018-11-20', 3),
(5,'2018-11-22', 12)

SELECT
RowID
, DueDate
, CASE
WHEN RowID = 1
THEN 0
WHEN RowID = LAST_VALUE(RowID) OVER(ORDER BY (SELECT NULL) )
THEN IncommingQuantity
WHEN ROW_NUMBER() OVER(PARTITION BY DueDate ORDER BY RowID) > 1
THEN IncommingQuantity
ELSE ICommitted - LAG(IncommingQuantity) OVER (ORDER BY RowID)
END IncommingQuantity
FROM @t2 t2
CROSS APPLY (SELECT t1.ICommitted FROM @t1 t1) e





share|improve this answer




















  • really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
    – MrB
    Nov 9 at 17:59

















up vote
0
down vote













I ended up doing this simply with WHILE loop inside a user function. The other solutions I would not work properly in 100% of cases






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53217377%2fcumulative-subtraction-across-rows%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    2
    down vote













    You need a cumulative sum and some arithmetic:



    select t.*,
    (case when running_iq - incomingquantity >= committed then 0
    when running_iq > committed then running_iq - committed
    else incomingquantity
    end) as from_this_row
    from (select t2.*, t1.committed,
    sum(incomingquantity) over (order by rowid) as running_iq
    from table1 t1 cross join
    table2 t2
    ) t;





    share|improve this answer






















    • Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
      – MrB
      Nov 8 at 23:39











    • @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
      – Gordon Linoff
      Nov 9 at 0:23














    up vote
    2
    down vote













    You need a cumulative sum and some arithmetic:



    select t.*,
    (case when running_iq - incomingquantity >= committed then 0
    when running_iq > committed then running_iq - committed
    else incomingquantity
    end) as from_this_row
    from (select t2.*, t1.committed,
    sum(incomingquantity) over (order by rowid) as running_iq
    from table1 t1 cross join
    table2 t2
    ) t;





    share|improve this answer






















    • Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
      – MrB
      Nov 8 at 23:39











    • @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
      – Gordon Linoff
      Nov 9 at 0:23












    up vote
    2
    down vote










    up vote
    2
    down vote









    You need a cumulative sum and some arithmetic:



    select t.*,
    (case when running_iq - incomingquantity >= committed then 0
    when running_iq > committed then running_iq - committed
    else incomingquantity
    end) as from_this_row
    from (select t2.*, t1.committed,
    sum(incomingquantity) over (order by rowid) as running_iq
    from table1 t1 cross join
    table2 t2
    ) t;





    share|improve this answer














    You need a cumulative sum and some arithmetic:



    select t.*,
    (case when running_iq - incomingquantity >= committed then 0
    when running_iq > committed then running_iq - committed
    else incomingquantity
    end) as from_this_row
    from (select t2.*, t1.committed,
    sum(incomingquantity) over (order by rowid) as running_iq
    from table1 t1 cross join
    table2 t2
    ) t;






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 9 at 0:23

























    answered Nov 8 at 22:58









    Gordon Linoff

    744k32285390




    744k32285390











    • Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
      – MrB
      Nov 8 at 23:39











    • @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
      – Gordon Linoff
      Nov 9 at 0:23
















    • Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
      – MrB
      Nov 8 at 23:39











    • @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
      – Gordon Linoff
      Nov 9 at 0:23















    Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
    – MrB
    Nov 8 at 23:39





    Interesting. But it doesn't seem to quite work for me. The result I get: I can't get it to format properly in comments... but it shows 0 for first row, 2 for second row... correct... but then starting 3rd row is is all 0s
    – MrB
    Nov 8 at 23:39













    @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
    – Gordon Linoff
    Nov 9 at 0:23




    @MrB . . . That is just the else part. You want how much is remaining, not how much is used, so it should be the original value.
    – Gordon Linoff
    Nov 9 at 0:23












    up vote
    1
    down vote













    you can also make use of the built-in functions such as ROW_NUMBER(), LAST_VALUE(), and LAG() with CASE



    here is an example :



    DECLARE 
    @t1 TABLE ( ProductID VARCHAR(50), ICommitted INT)

    INSERT INTO @t1 VALUES ('Some product', 7)

    DECLARE
    @t2 TABLE (RowID INT, DueDate DATE, IncommingQuantity INT)

    INSERT INTO @t2 VALUES
    (1,'2018-11-19', 5),
    (2,'2018-11-20', 4),
    (3,'2018-11-20', 4),
    (4,'2018-11-20', 3),
    (5,'2018-11-22', 12)

    SELECT
    RowID
    , DueDate
    , CASE
    WHEN RowID = 1
    THEN 0
    WHEN RowID = LAST_VALUE(RowID) OVER(ORDER BY (SELECT NULL) )
    THEN IncommingQuantity
    WHEN ROW_NUMBER() OVER(PARTITION BY DueDate ORDER BY RowID) > 1
    THEN IncommingQuantity
    ELSE ICommitted - LAG(IncommingQuantity) OVER (ORDER BY RowID)
    END IncommingQuantity
    FROM @t2 t2
    CROSS APPLY (SELECT t1.ICommitted FROM @t1 t1) e





    share|improve this answer




















    • really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
      – MrB
      Nov 9 at 17:59














    up vote
    1
    down vote













    you can also make use of the built-in functions such as ROW_NUMBER(), LAST_VALUE(), and LAG() with CASE



    here is an example :



    DECLARE 
    @t1 TABLE ( ProductID VARCHAR(50), ICommitted INT)

    INSERT INTO @t1 VALUES ('Some product', 7)

    DECLARE
    @t2 TABLE (RowID INT, DueDate DATE, IncommingQuantity INT)

    INSERT INTO @t2 VALUES
    (1,'2018-11-19', 5),
    (2,'2018-11-20', 4),
    (3,'2018-11-20', 4),
    (4,'2018-11-20', 3),
    (5,'2018-11-22', 12)

    SELECT
    RowID
    , DueDate
    , CASE
    WHEN RowID = 1
    THEN 0
    WHEN RowID = LAST_VALUE(RowID) OVER(ORDER BY (SELECT NULL) )
    THEN IncommingQuantity
    WHEN ROW_NUMBER() OVER(PARTITION BY DueDate ORDER BY RowID) > 1
    THEN IncommingQuantity
    ELSE ICommitted - LAG(IncommingQuantity) OVER (ORDER BY RowID)
    END IncommingQuantity
    FROM @t2 t2
    CROSS APPLY (SELECT t1.ICommitted FROM @t1 t1) e





    share|improve this answer




















    • really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
      – MrB
      Nov 9 at 17:59












    up vote
    1
    down vote










    up vote
    1
    down vote









    you can also make use of the built-in functions such as ROW_NUMBER(), LAST_VALUE(), and LAG() with CASE



    here is an example :



    DECLARE 
    @t1 TABLE ( ProductID VARCHAR(50), ICommitted INT)

    INSERT INTO @t1 VALUES ('Some product', 7)

    DECLARE
    @t2 TABLE (RowID INT, DueDate DATE, IncommingQuantity INT)

    INSERT INTO @t2 VALUES
    (1,'2018-11-19', 5),
    (2,'2018-11-20', 4),
    (3,'2018-11-20', 4),
    (4,'2018-11-20', 3),
    (5,'2018-11-22', 12)

    SELECT
    RowID
    , DueDate
    , CASE
    WHEN RowID = 1
    THEN 0
    WHEN RowID = LAST_VALUE(RowID) OVER(ORDER BY (SELECT NULL) )
    THEN IncommingQuantity
    WHEN ROW_NUMBER() OVER(PARTITION BY DueDate ORDER BY RowID) > 1
    THEN IncommingQuantity
    ELSE ICommitted - LAG(IncommingQuantity) OVER (ORDER BY RowID)
    END IncommingQuantity
    FROM @t2 t2
    CROSS APPLY (SELECT t1.ICommitted FROM @t1 t1) e





    share|improve this answer












    you can also make use of the built-in functions such as ROW_NUMBER(), LAST_VALUE(), and LAG() with CASE



    here is an example :



    DECLARE 
    @t1 TABLE ( ProductID VARCHAR(50), ICommitted INT)

    INSERT INTO @t1 VALUES ('Some product', 7)

    DECLARE
    @t2 TABLE (RowID INT, DueDate DATE, IncommingQuantity INT)

    INSERT INTO @t2 VALUES
    (1,'2018-11-19', 5),
    (2,'2018-11-20', 4),
    (3,'2018-11-20', 4),
    (4,'2018-11-20', 3),
    (5,'2018-11-22', 12)

    SELECT
    RowID
    , DueDate
    , CASE
    WHEN RowID = 1
    THEN 0
    WHEN RowID = LAST_VALUE(RowID) OVER(ORDER BY (SELECT NULL) )
    THEN IncommingQuantity
    WHEN ROW_NUMBER() OVER(PARTITION BY DueDate ORDER BY RowID) > 1
    THEN IncommingQuantity
    ELSE ICommitted - LAG(IncommingQuantity) OVER (ORDER BY RowID)
    END IncommingQuantity
    FROM @t2 t2
    CROSS APPLY (SELECT t1.ICommitted FROM @t1 t1) e






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 9 at 1:14









    iSR5

    1,338278




    1,338278











    • really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
      – MrB
      Nov 9 at 17:59
















    • really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
      – MrB
      Nov 9 at 17:59















    really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
    – MrB
    Nov 9 at 17:59




    really nice! I have not used LAG or LAST_VALUE before. These are great for improving readability and reducing complexity
    – MrB
    Nov 9 at 17:59










    up vote
    0
    down vote













    I ended up doing this simply with WHILE loop inside a user function. The other solutions I would not work properly in 100% of cases






    share|improve this answer
























      up vote
      0
      down vote













      I ended up doing this simply with WHILE loop inside a user function. The other solutions I would not work properly in 100% of cases






      share|improve this answer






















        up vote
        0
        down vote










        up vote
        0
        down vote









        I ended up doing this simply with WHILE loop inside a user function. The other solutions I would not work properly in 100% of cases






        share|improve this answer












        I ended up doing this simply with WHILE loop inside a user function. The other solutions I would not work properly in 100% of cases







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 9 at 20:05









        MrB

        365




        365



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53217377%2fcumulative-subtraction-across-rows%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Darth Vader #20

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Ondo