Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get the last plus and last minus datetime from a stock table

I have an SQL table with the following structure:

Table Structure

CREATE DATABASE TestDB;
GO
USE TestDB;
CREATE TABLE dbo.TestForStock
( ID INT IDENTITy(1,1)
,WarehouseID BIGINT
,ItemID BIGINT
,Qty INT
,DatetimeStamp datetime
,Remarks NVARCHAR(100)
)

INSERT INTO dbo.TestForStock
SELECT 20,392,100, '2023-06-28 16:57:43.143','Item Added' UNION ALL
SELECT 20,392,-1, '2023-06-29 15:54:41.997','Item removed' UNION ALL
SELECT 20,392,-1, '2023-06-29 15:54:42.037','Item removed' UNION ALL
SELECT 20,128,50, '2023-06-20 17:38:43.030','Item Added' UNION ALL
SELECT 20,128,-1, '2023-06-21 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,-1, '2023-06-22 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,10, '2023-06-25 17:38:43.030','Item Added' UNION ALL
SELECT 20,128,-1, '2023-06-26 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,-1, '2023-06-27 17:38:43.030','Item removed' 

This is a warehouse item stock table having entries of each transaction when item was added or removed from a warehouse.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I want to get the age of items in their warehouses, so for that I want to get the latest date when any item was added in any warehouse and the latest date when it was moved from the warehouse(means date of the latest plus and minus qty field).

How can I do it, I tried doing it via the following sql, but its way too slow and not efficient and it should be done in a single query:

SELECT TOP 1
    W.Code AS WarehouseCode,
    W.Name AS WarehouseName,
    I.Code AS SKU,
    I.Name AS ItemName,
    CONVERT(VARCHAR(20), WS.DateTimeStamp ,106) AS LastPlusDatetime
FROM WareHouse W WITH(NOLOCK)
INNER JOIN WareHouseStock WS WITH(NOLOCK) ON WS.WareHouseID = W.ID
INNER JOIN Item I WITH(NOLOCK) ON WS.ItemID = I.ID
WHERE W.Code = @WarehouseCode
AND I.Code = @SKU
AND Qty > 0
ORDER BY WS.ID DESC

SELECT TOP 1
    W.Code AS WarehouseCode,
    W.Name AS WarehouseName,
    I.Code AS SKU,
    I.Name AS ItemName,
    CONVERT(VARCHAR(20), WS.DateTimeStamp ,106) AS LastMinusDatetime
FROM WareHouse W WITH(NOLOCK)
INNER JOIN WareHouseStock WS WITH(NOLOCK) ON WS.WareHouseID = W.ID
INNER JOIN Item I WITH(NOLOCK) ON WS.ItemID = I.ID
WHERE W.Code = @WarehouseCode
AND I.Code = @SKU
AND Qty < 0
ORDER BY WS.ID DESC

For the provided schema example, the expected result should be:

20 392 100 ‘2023-06-28 16:57:43.143’ AS LatestPlusDate ‘2023-06-29 15:54:42.037’ AS LatestMinusDate

20 128 10 ‘2023-06-25 17:38:43.030’ AS LatestPlusDate ‘2023-06-27 17:38:43.030’ AS LatestMinusDate

>Solution :

Something like this perhaps?

CREATE TABLE dbo.TestForStock
( ID INT IDENTITy(1,1)
,WarehouseID BIGINT
,ItemID BIGINT
,Qty INT
,DatetimeStamp datetime
,Remarks NVARCHAR(100)
)

INSERT INTO dbo.TestForStock
SELECT 20,392,100, '2023-06-28 16:57:43.143','Item Added' UNION ALL
SELECT 20,392,-1, '2023-06-29 15:54:41.997','Item removed' UNION ALL
SELECT 20,392,-1, '2023-06-29 15:54:42.037','Item removed' UNION ALL
SELECT 20,128,50, '2023-06-20 17:38:43.030','Item Added' UNION ALL
SELECT 20,128,-1, '2023-06-21 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,-1, '2023-06-22 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,10, '2023-06-25 17:38:43.030','Item Added' UNION ALL
SELECT 20,128,-1, '2023-06-26 17:38:43.030','Item removed' UNION ALL
SELECT 20,128,-1, '2023-06-27 17:38:43.030','Item removed' 

select warehouseid, itemid
,   max(case when qty > 0 then datetimestamp end) as incoming
,   max(case when qty < 0 then datetimestamp end) as outgoing
from TestForStock
group by warehouseid, ItemID

max(case when qty < 0 then datetimestamp end) is a technique called conditional aggregation, where you get the value you want by using a CASE WHEN condition which filters out what you want.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading