sqlsql-serverdatabasedatabase-designinventory-management

Calculate stock OpeningQuantity, QuantityIn, QuantityOut and ClosingQuantity


I have two tables Item and LineItem.

Items Table

ItemId Name Quantity
1 Shampoo 2
2 Soap 0

LineItems Table

LineItemId ItemId QuantityIn QuantityOut DateCreated
1 1 1 0 2021-05-04
2 1 1 0 2021-05-05

Now if I want to return OpeningQuantity, QuantityIn, QuantityOut and CurrentQuantity between 2021-05-01 and 2021-05-04 inclusive using a query it should return like this:

ItemId Name Begining Quantity QuantityIn QuantityOut CurrentQuantity
1 Shampoo 0 1 1

And if I want to return OpeningQuantity, QuantityIn, QuantityOut and CurrentQuantity between 2021-05-04 and 2021-05-05 inclusive using a query it should return like this:

ItemId Name Begining Quantity QuantityIn QuantityOut CurrentQuantity
1 Shampoo 1 1 2
select
    items.ItemId as id,
    items.name as name,
    (
        select sum(quantityin - quantityout)
        from lineitems
        where
            ItemId = items.ItemId
            and datecreated < '2021-05-04'
    ) as beginning,
    (
        select sum(quantityin)
        from lineitems
        where
            ItemId = items.ItemId
            and datecreated >= '2021-05-04'
            and datecreated <= '2021-05-04'
    ) as quantity_in,
    (
        select sum(quantityout)
        from lineitems
        where
            ItemId = items.ItemId
            and datecreated >= '2021-05-04'
            and datecreated <= '2021-05-04'
    ) as quantity_out,
    (
        (
            select sum(quantityin - quantityout)
            from lineitems
            where
                ItemId = items.ItemId
                and datecreated < '2021-05-04'
        ) + sum(lineitems.QuantityIn - lineitems.QuantityOut)
    ) as closing_quantity
from
    items
    inner join LineItems as lineitems on items.itemid = LineItems.itemid
where
    lineitems.DateCreated >= '2021-05-04'
    and lineitems.DateCreated <= '2021-05-04'
group by
    items.name,
    items.ItemId

I have tried this query which extract each column data using subqueries but the closing_quantity is not returning anything and also this query does not seem efficient because for beginning_quantity we have to search entire table from date above until the very first record and sum it up.

Can anyone help me what query should I use or redesign the tables.


Solution

  • If I understand correctly , here is what you want to do :

    select   
        items.ItemId
        , items.name
        ,coalesce(sum(quantityin-quantityout) filter (where DateCreated <= '2021-05-01'),0)  beginning
        ,sum(quantityin) filter (where DateCreated > '2021-05-01') QuantityIn
        ,sum(quantityout) filter (where DateCreated > '2021-05-01') QuantityOut
        ,sum(quantityin - quantityout)  CurrentQuantity
    from items
    inner join LineItems 
        on items.itemid = LineItems.itemid
    where lineitems.DateCreated <= '2021-05-04'
    group by
        items.name,items.ItemId;
    

    I wrote in postgresql syntax , here is standard sql syntax:

    select   
        items.ItemId
        , items.name
        ,sum(case when DateCreated <='2021-05-01' then quantityin-quantityout else 0 end) beginning
        ,sum(case when DateCreated > '2021-05-01' then quantityin else 0 end) QuantityIn
        ,sum(case when DateCreated > '2021-05-01' then quantityout else 0 end) QuantityOut
        ,sum(quantityin - quantityout)  CurrentQuantity
    from items
    inner join LineItems 
        on items.itemid = LineItems.itemid
    where lineitems.DateCreated <= '2021-05-04'
    group by
        items.name,items.ItemId;