I have a table containing transaction information on items. The possible transactions are purchase (type_id: 1) and sale(type_id: 2). A really stripped down version of the table “Transactions” is like the following:
Transaction_ID Item_ID Transaction_Type_ID Quantity Price Date
1, 1, 1, 50, 10, 6/1,
2, 2, 1, 40, 20, 13/1,
3, 1, 2, 10, 13, 14/1,
4, 2, 2, 20, 25, 3/2,
5, 1, 2, 20, 12, 20/2
I have the following query:
SELECT B.Item_ID
B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2) AS 'Quantity Left'
B.Price * (B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2)) AS 'Purchase Amount Left'
FROM Transaction B
WHERE B.Transaction_Type_ID = 1
AND B.Quantity - (SELECT SUM(Quantity) FROM Transactions A Where A.Item_ID = B.Item_ID AND A.Transaction_Type_ID = 2) > 0
Like you may already noticed, I am trying to get all the purchased items that are still in stock. You may notice also that there is an annoying sub-query repeating twice in the SELECT clause and once in the WHERE clause.
How can I reduce it? Is it possible to use WITH in the beginning of the statement in this case?
JOIN onto an aggregated derived table?
If you always have rows where Transaction_Type_ID = 2, then you can remove LEFT JOIN and ISNULL. In your current code, you assume you always have rows.
It also looks like you’re mixing entities in the same table based on Transaction_Type_ID. A simple
SUM(Quantity) .. GROUP BY Item_IDwould be more correct if– sales are <0 quantity transaction
– restocks are >0 quantity transaction2