SQL Running Subtraction

前端 未结 3 753
一整个雨季
一整个雨季 2021-01-07 01:44

I have a result set as below:

Item    ExpectedQty  ReceivedQty  Short
Item01  30           45           5
Item01  20           45           5

Item02  40             


        
相关标签:
3条回答
  • 2021-01-07 02:17

    One part of the problem is to get the running totals of expected item qunatities. For that you'd need a way to distinguish rows with same items from each other and a rule for the order of discharging same item quantities.

    For the purpose of my attempt at solving your problem I'm going to assume there's a timestamp column whose values provide the order of discharge and are unique within same item groups.

    Here's the sample data definition I was testing my solution on:

    CREATE TABLE TableA (Item varchar(50), ExpectedQty int, Timestamp int);
    INSERT INTO TableA
    SELECT 'Item01', 30, 1 UNION ALL
    SELECT 'Item01', 20, 2 UNION ALL
    SELECT 'Item02', 40, 1 UNION ALL
    SELECT 'item03', 50, 1 UNION ALL
    SELECT 'item03', 30, 2 UNION ALL
    SELECT 'item03', 20, 3;
    
    CREATE TABLE TableB (Item varchar(50), ReceivedQty int);
    INSERT INTO TableB
    SELECT 'Item01', 45 UNION ALL
    SELECT 'Item02', 38 UNION ALL
    SELECT 'item03', 90;
    

    And here's my solution:

    SELECT
      Item,
      ExpectedQty,
      ReceivedQty = CASE
        WHEN RemainderQty >= 0 THEN ExpectedQty
        WHEN RemainderQty < -ExpectedQty THEN 0
        ELSE RemainderQty + ExpectedQty
      END,
      Short = CASE
        WHEN RemainderQty >= 0 THEN 0
        WHEN RemainderQty < -ExpectedQty THEN ExpectedQty
        ELSE ABS(RemainderQty)
      END
    FROM (
      SELECT
        a.Item,
        a.ExpectedQty,
        RemainderQty = b.ReceivedQty - a.RunningTotalQty
      FROM (
        SELECT
          a.Item,
          a.Timestamp,
          a.ExpectedQty,
          RunningTotalQty = SUM(a2.ExpectedQty)
        FROM TableA a
          INNER JOIN TableA a AS a2 ON a.Item = a2.Item AND a.Timestamp >= a2.Timestamp
        GROUP BY
          a.Item,
          a.Timestamp,
          a.ExpectedQty
      ) a
        INNER JOIN TableB b ON a.Item = b.Item
    ) s
    
    0 讨论(0)
  • 2021-01-07 02:30
    select a.Item, a.ExpectedQty,b.ReceivedQty, (a.ExpectedQty - b.ReceivedQty) as 'Short' from a join b on a.Item = b.Item
    
    0 讨论(0)
  • 2021-01-07 02:38
    SELECT  a.ExpectedQty,
        b.ReceivedQty,
        CASE WHEN b.ReceivedQty < a.ExpectedQty
             THEN b.ReceivedQty - a.ExpectedQty
             ELSE 0
        END Short
    FROM    dbo.a a
    INNER JOIN dbo.b b
    ON      a.ItemId = b.ItemId
    
    0 讨论(0)
提交回复
热议问题