Reputation: 864
I want to Calculate Balance Quantity on the basis of top records fetched in my query.
My query is like as follows -
SELECT ItemLedger.Code as Code,
ISNULL(MstOrganization.Name,'') AS OrganizationName,
ISNULL(stmVoucherType.Name,'') AS VoucherTypeName,
ISNULL(stmItem.Name,'') AS ItemName,
ISNULL(stmItem.IsProductTag,0) AS IsProductTag,
ItemLedger.InOut AS [InOut],
ItemLedger.ItemCode,
ItemLedger.Quantity As Quantity,
CASE WHEN ItemLedger.Inout = 0
THEN ItemLedger.Quantity
ELse 0
End as InwardQuantity,
CASE WHEN ItemLedger.Inout = 1
THEN ItemLedger.Quantity * (-1)
ELse 0
End as OutwardQuantity,
SUM((CASE WHEN ItemLedger.Inout = 0
THEN ItemLedger.Quantity
ELse 0
End) -
(CASE WHEN ItemLedger.Inout = 1
THEN ItemLedger.Quantity
ELse 0
End)) as BalanceQuantity
FROM VIEW_ITEM_STOCK_LEDGER as ItemLedger
LEFT JOIN MstGroup ON MstGroup.Code = ItemLedger.GroupCode
LEFT JOIN MstOrganization ON MstOrganization.Code = ItemLedger.OrganizationCode
LEFT JOIN MstCurrency As BaseCurrency On BaseCurrency.Code = MstOrganization.CurrencyCode
LEFT JOIN stmVoucherType ON stmVoucherType.Code = ItemLedger.VoucherTypeCode
LEFT JOIN MstCurrency As DocumentCurrency ON DocumentCurrency.Code = ItemLedger.DocumentCurrencyCode
LEFT JOIN MstUser ON MstUser.Code = ItemLedger.UserCode
LEFT JOIN MstUOM As DetailUOM ON DetailUOM.Code = ItemLedger.DetailUOMCode
LEFT JOIN stmItem ON stmItem.Code = ItemLedger.ItemCode
LEFT JOIN MstUOM As ItemUOM ON ItemUOM.Code = stmItem.UOMCode
LEFT JOIN mstProductCategory ON mstProductCategory.Code = stmItem.ProductCategoryCode
LEFT JOIN mstTax ON mstTax.Code = ItemLedger.TaxCode
LEFT JOIN MstStockPoint ON MstStockPoint.Code = ItemLedger.StockPointCode
LEFT JOIN dbo.SplitCode('110,112,145,162,163,164,165,166,167,226,323,324,326,354,376') As OrgCode ON OrgCode.Code = ItemLedger.OrganizationCode
LEFT JOIN TranProductTagging ON TranProductTagging.Code = ItemLedger.ItemCode
WHERE ((CASE WHEN 1 = 0
THEN (CASE WHEN ISNULL((ItemLedger.Quantity),0) <> 0
THEN 1
ELSE 0
END
)
ELSE 1
END
) = 1) AND (ItemLedger.FilterDocumentDate <= '2018-10-25' AND ItemLedger.TransactionType = 0)
AND ItemLedger.VoucherTypeCode not in (107, --@AXS_VOUCHERTYPE_STOCKPOINTTRANSFER
402, --@AXS_VOUCHERTYPE_STOCKIN
403) --@AXS_VOUCHERTYPE_STOCKOUT
AND StmItem.IsProductTag = 0 -- Tag Items
AND ItemLedger.OrganizationKey Like ('' + 'AABA' + '%') AND
((Len(ISNULL('10046406','')) > 0 AND ItemLedger.itemcode in (select * from dbo.SplitCode('10046406')))
OR Len(ISNULL('10046406','')) = 0 AND 1=1)
group by ItemLedger.Code,MstOrganization.Name,stmVoucherType.Name,stmItem.Name,stmItem.IsProductTag,
ItemLedger.InOut,ItemLedger.ItemCode,ItemLedger.Quantity
This Query is producing Output as Follows -
But, field Balance Quantity is fetching wrong,
My Required O/P for Balance Quantity Field -
BalanceQuantity
12
10
Any help would be appreciated.
Upvotes: 1
Views: 82
Reputation: 29943
Explanation:
You may try with SUM(..) OVER (PARTITTION BY ...)
. I'm not able to reproduce and test this without actual data, but you may try with this:
WITH ResultValues (
Code,
OrganizationName,
VoucherTypeName,
ItemName,
IsProductTag,
InOut,
ItemCode,
Quantity,
InwardQuantity,
OutwardQuantity
) AS (
-- Your statement here
)
SELECT
*,
SUM(InwardQuantity + OutwardQuantity) OVER (PARTITION BY ItemCode ORDER BY ItemCode) AS BalanceQuantity
FROM ResultValues
Working example:
Below is working example that demonstrates this approach:
DECLARE @ItemTable TABLE (
ItemID varchar(100),
ItemDate date,
ItemIn numeric(10, 2),
ItemOut numeric(10, 2)
);
INSERT INTO @Itemtable VALUES
('001', '2018-01-10', 10.01, 0),
('001', '2018-02-10', 10.02, 0),
('001', '2018-03-10', 10.03, 0),
('001', '2018-04-10', 0, -10.04),
('001', '2018-05-10', 10.05, 0),
('002', '2018-01-10', 20.01, 0),
('002', '2018-02-10', 20.02, 0),
('002', '2018-03-10', 20.03, 0),
('002', '2018-04-10', 20.04, 0),
('002', '2018-05-10', 20.05, 0),
('003', '2018-01-10', 30.01, 0),
('003', '2018-02-10', 0, -30.02);
SELECT
ItemID,
ItemDate,
ItemIn,
ItemOut,
SUM(ItemIn + ItemOut) OVER (PARTITION BY ItemID ORDER BY ItemDate) AS ItemBalance
FROM @ItemTable
Output:
ItemID ItemDate ItemIn ItemOut ItemBalance
001 2018-01-10 10.01 0.00 10.01
001 2018-02-10 10.02 0.00 20.03
001 2018-03-10 10.03 0.00 30.06
001 2018-04-10 0.00 -10.04 20.02
001 2018-05-10 10.05 0.00 30.07
002 2018-01-10 20.01 0.00 20.01
002 2018-02-10 20.02 0.00 40.03
002 2018-03-10 20.03 0.00 60.06
002 2018-04-10 20.04 0.00 80.10
002 2018-05-10 20.05 0.00 100.15
003 2018-01-10 30.01 0.00 30.01
003 2018-02-10 0.00 -30.02 -0.01
Update:
For SQL Server versions, that do not fully support SUM(...) OVER (...)
, try with this:
SELECT
i.ItemID,
i.ItemDate,
i.ItemIn,
i.ItemOut,
(
SELECT SUM(s.ItemIn + s.ItemOut)
FROM @ItemTable s
WHERE (i.ItemID = s.ItemId) AND (i.ItemDate >= s.ItemDate)
) AS ItemBalance
FROM @ItemTable i
ORDER BY i.ItemID, i.ItemDate
Upvotes: 1
Reputation: 95561
You would probably be better putting the entire query in a CTE and then using LAG
. Note that I've put comments around the PARTITION BY
as there isn't enough information for me to infer if it is needed, or what it should be if it is:
WITH CTE AS(
SELECT ItemLedger.Code AS Code,
ISNULL(MstOrganization.Name, '') AS OrganizationName,
ISNULL(stmVoucherType.Name, '') AS VoucherTypeName,
ISNULL(stmItem.Name, '') AS ItemName,
ISNULL(stmItem.IsProductTag, 0) AS IsProductTag,
ItemLedger.InOut AS [InOut],
ItemLedger.ItemCode,
ItemLedger.Quantity AS Quantity,
CASE WHEN ItemLedger.Inout = 0 THEN ItemLedger.Quantity ELSE 0 END AS InwardQuantity,
CASE WHEN ItemLedger.Inout = 1 THEN ItemLedger.Quantity * (-1) ELSE 0 END AS OutwardQuantity,
SUM((CASE WHEN ItemLedger.Inout = 0 THEN ItemLedger.Quantity ELSE 0 END) - (CASE WHEN ItemLedger.Inout = 1 THEN ItemLedger.Quantity ELSE 0 END)) AS BalanceQuantity
FROM VIEW_ITEM_STOCK_LEDGER ItemLedger
LEFT JOIN MstGroup ON MstGroup.Code = ItemLedger.GroupCode
LEFT JOIN MstOrganization ON MstOrganization.Code = ItemLedger.OrganizationCode
LEFT JOIN MstCurrency BaseCurrency ON BaseCurrency.Code = MstOrganization.CurrencyCode
LEFT JOIN stmVoucherType ON stmVoucherType.Code = ItemLedger.VoucherTypeCode
LEFT JOIN MstCurrency DocumentCurrency ON DocumentCurrency.Code = ItemLedger.DocumentCurrencyCode
LEFT JOIN MstUser ON MstUser.Code = ItemLedger.UserCode
LEFT JOIN MstUOM DetailUOM ON DetailUOM.Code = ItemLedger.DetailUOMCode
LEFT JOIN stmItem ON stmItem.Code = ItemLedger.ItemCode
LEFT JOIN MstUOM ItemUOM ON ItemUOM.Code = stmItem.UOMCode
LEFT JOIN mstProductCategory ON mstProductCategory.Code = stmItem.ProductCategoryCode
LEFT JOIN mstTax ON mstTax.Code = ItemLedger.TaxCode
LEFT JOIN MstStockPoint ON MstStockPoint.Code = ItemLedger.StockPointCode
LEFT JOIN dbo.SplitCode('110,112,145,162,163,164,165,166,167,226,323,324,326,354,376') OrgCode ON OrgCode.Code = ItemLedger.OrganizationCode
LEFT JOIN TranProductTagging ON TranProductTagging.Code = ItemLedger.ItemCode
WHERE ((CASE
WHEN 1 = 0 THEN (CASE WHEN ISNULL((ItemLedger.Quantity), 0) <> 0 THEN 1 ELSE 0 END)
ELSE 1
END) = 1)
AND (ItemLedger.FilterDocumentDate <= '2018-10-25'
AND ItemLedger.TransactionType = 0)
AND ItemLedger.VoucherTypeCode NOT IN (107, --@AXS_VOUCHERTYPE_STOCKPOINTTRANSFER
402, --@AXS_VOUCHERTYPE_STOCKIN
403) --@AXS_VOUCHERTYPE_STOCKOUT
AND stmItem.IsProductTag = 0 -- Tag Items
AND ItemLedger.OrganizationKey LIKE ('' + 'AABA' + '%')
AND ((LEN(ISNULL('10046406', '')) > 0
AND ItemLedger.itemcode IN (SELECT * FROM dbo.SplitCode('10046406') ))
OR LEN(ISNULL('10046406', '')) = 0
AND 1 = 1)
GROUP BY ItemLedger.Code,
MstOrganization.Name,
stmVoucherType.Name,
stmItem.Name,
stmItem.IsProductTag,
ItemLedger.InOut,
ItemLedger.ItemCode,
ItemLedger.Quantity)
SELECT CTE.OrganizationName,
CTE.VoucherTypeName,
CTE.ItemName,
CTE.IsProductTag,
CTE.InwardQuantity,
CTE.OutwardQuantity,
CTE.BalanceQuantity + LAG(CTE.BalanceQuantity,1,0) OVER (/*PARTITION BY ??? */ ORDER BY [Code]) AS BalanceQuantity
FROM CTE;
Note: The OP has only given use a 2 row sample, I wonder is this is actually meant to be a running total, if there are 3 or more rows. Impossible to know with the limited information as well.
Upvotes: 0